Dependency injection 哪种依赖注入;“工厂”;使用?

Dependency injection 哪种依赖注入;“工厂”;使用?,dependency-injection,inversion-of-control,unity-container,Dependency Injection,Inversion Of Control,Unity Container,我有两个选项可以创建ViewModel工厂以注入到其他类中: 方案A public interface IFactory { ViewModelA CreateViewModelA(string data); ViewModelB CreateViewModelB(string data); } public class MyFactory : IFactory { public MyFactory(){} public ViewModelA CreateVi

我有两个选项可以创建ViewModel工厂以注入到其他类中:

方案A

public interface IFactory
{
    ViewModelA CreateViewModelA(string data);
    ViewModelB CreateViewModelB(string data);
}

public class MyFactory : IFactory
{
    public MyFactory(){}

    public ViewModelA CreateViewModelA(string data)
    {
        return new ViewModelA (data);
    }

    public ViewModelA CreateViewModelB(string data)
    {
        return new ViewModelB (data);
    }
}
//register factory
container.RegisterType<IFactory, MyFactory>(new ContainerControlledLifetimeManager());
公共接口IFactory
{
ViewModelA CreateViewModelA(字符串数据);
ViewModelB CreateViewModelB(字符串数据);
}
公共类MyFactory:IFactory
{
公共MyFactory(){}
公共ViewModelA CreateViewModelA(字符串数据)
{
返回新的ViewModelA(数据);
}
公共ViewModelA CreateViewModelB(字符串数据)
{
返回新的ViewModelB(数据);
}
}
//注册工厂
RegisterType(新的ContainerControlledLifetimeManager());
方案B

public interface IFactory
{
    T CreateViewModel<T>();
}
public class MyFactory : IFactory
{
    public MyFactory(IUnityContainer unityContainer)
    {
        _container = unityContainer;
    }
    private IUnityContainer _container { get; set; }

    public T CreateViewModel<T>()
    {
        return (T)this._container.Resolve<T>();
    }
}
//register factory
var container = new UnityContainer();
container.RegisterType<IFactory, MyFactory>(new ContainerControlledLifetimeManager(), new InjectionConstructor(container));
//inject this where neccessary
公共接口IFactory
{
T CreateViewModel();
}
公共类MyFactory:IFactory
{
公共MyFactory(IUnityContainer unityContainer)
{
_容器=unityContainer;
}
私有IUnityContainer_容器{get;set;}
公共T CreateViewModel()
{
返回(T)此._container.Resolve();
}
}
//注册工厂
var container=new UnityContainer();
RegisterType(新的ContainerControlledLifetimeManager(),新的InjectionConstructor(容器));
//在必要的地方注射

选项B似乎更容易实现,但我不确定以这种方式使用容器是否正确。我读过关于服务定位器反模式的文章,在这种情况下,我将容器传递给另一个类的构造函数的方式似乎类似于这个问题。那么,我应该选择哪一个选项?如果可能的话,详细说明原因是什么?

出于一些原因,我支持选项A

首先,在选项B中,
MyFactory
实际上什么都不做。即使是泛型强制转换
也返回(T)this.\u container.Resolve()
是冗余的,所以它只不过是一个over
IUnityContainer
。在所有依赖于
IFactory
的B版本的代码中,您也可以直接依赖于
IUnityContainer
(暂时忽略)

第二,尽管,
IUnityContainer
(因此也是选项B)是一个。一个问题是,它可以在编译时调用,但在运行时会失败。它也是

另一方面,选项A。它只提供有限的API。不过,我可能会选择通用接口:

public interface IFactory<T>
{
    T Create(object context);
}
公共接口IFactory
{
T创建(对象上下文);
}
是的,但请记住,软件开发是一个重要的方面。不应该决定哪种替代方案最容易实现,而应该决定哪种版本的代码最容易理解


阅读代码比编写代码花费的时间多得多。

感谢您的回答和提供的链接,这是一本非常好的读物。我会坚持选择A!