0

我有一个具有 DAL 依赖项的类:

public class FirstClass()
{
    [Dependency]
    public IDalType Dal { get; set; }
}

我可以创建一个类的实例:

UnityContainer c = new UnityContainer();  
c.RegisterType<IDalType, DalType>();
FirstClass fc = c.Resolve<FirstClass>();

这将设置依赖项,我可以使用该实例。这有点像一个开始的主类(主窗体,主 ViewModel)。

现在,我SecondClass又有了一个 DAL 依赖项,并且必须实例化第二个类并从第一个类调用。我怎么做?

public class FirstClass()
{
    [Dependency]
    public IDalType Dal { get; set; }

    public DoSomething()
    {
        ??? SecondClass sc = App.UnityContainer.Resolve<SecondClass>();
    }
}

如果我在第一个类中使用 UnityContainer,那将是与容器的耦合,我必须在应用程序根目录中的某个位置映射 IDAL -> DAL 并拥有一个静态容器。

我读到与容器的耦合不好,以及使用静态地图: http ://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx

4

2 回答 2

1

添加 SecondClass 作为 FirstClass 的依赖项:

public class FirstClass
{
    [Dependency]
    public IDalType Dal { get; set; }

    [Dependency]
    public SecondClass Sc { get; set; }

    public DoSomething()
    {
        sc.DoWhatever();
    }
}

但是,我强烈建议改用构造函数注入:

public class FirstClass
{
    private IDalType dal;
    private SecondClass sc;

    public FirstClass(IDalType dal, SecondClass sc) 
    {
        this.dal = dal;
        this.sc = sc;
    }

    public DoSomething()
    {
        sc.DoWhatever();
    }
}

这样,您就不会通过属性与容器耦合,也不会公开仅作为输入存在的属性(混淆您的类的公共接口),并且您保证在没有它的情况下无法创建 FirstClass 的实例它需要的所有依赖项。

更新

如果您需要按需创建实例,则可以改为注入 Func。Unity 将为您创建一个工厂方法,在调用该方法时,将回调到容器中。

public class FirstClass
{
    private IDalType dal;
    private Func<SecondClass> scFactory;

    public FirstClass(IDalType dal, Func<SecondClass> scFactory) 
    {
        this.dal = dal;
        this.scFactory = scFactory;
    }

    public DoSomething()
    {
        SecondClass cs = scFactory();
        sc.DoWhatever();
    }
}

如果您有更复杂的要求来选择哪个辅助对象做什么,我会重新评估您是否应该从容器中获取有问题的对象。相反,请考虑注入显式工厂对象。

于 2012-06-11T16:54:09.817 回答
1

使用工厂会将有关服务(您的)实例化的一些知识SecondClass放入您的消费者中。在这篇文章中, Mark Seemann 描述了另一种方法。

如果您不想浪费时间和精力对这些类型的适配器进行编码,请查看CodePlex 上的 TecX 项目。它增加了对使用 Unity 即时生成惰性代理的支持。

于 2012-06-12T00:00:17.873 回答