Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 问题及;关于IoC、合成根、servicelocator、工厂的思考_C#_Ioc Container_Service Locator - Fatal编程技术网

C# 问题及;关于IoC、合成根、servicelocator、工厂的思考

C# 问题及;关于IoC、合成根、servicelocator、工厂的思考,c#,ioc-container,service-locator,C#,Ioc Container,Service Locator,我一直在寻找一种正确使用IoC容器的好方法,即: 严格按要求使用容器 不使用公共ServiceLocator(或类似工具)来避免可测试性问题 我现在开始学习新东西的个人项目,这是一个WPF(4.5)MVVM应用程序,它使用WCF、EntityFramework以及其他技术、框架、模式和实践,我想尝试不同的方法来充分利用容器、工厂和相关模式 我想到的一个想法是创建一个通用工厂,它可以在合成根目录下设置,而不需要传递容器引用。这应该避免可测试性问题。例如,我们有一个工厂: class Facto

我一直在寻找一种正确使用IoC容器的好方法,即:

  • 严格按要求使用容器
  • 不使用公共ServiceLocator(或类似工具)来避免可测试性问题
我现在开始学习新东西的个人项目,这是一个WPF(4.5)MVVM应用程序,它使用WCF、EntityFramework以及其他技术、框架、模式和实践,我想尝试不同的方法来充分利用容器、工厂和相关模式


我想到的一个想法是创建一个通用工厂,它可以在合成根目录下设置,而不需要传递容器引用。这应该避免可测试性问题。例如,我们有一个工厂:

class Factory
{
    private static Dictionary<Type, Func<object>> Store = new Dictionary<Type,Func<object>>();

    public static void Setup<T>(Func<T> Creation)
    {
        Store.Add(typeof(T), () => Creation());
    }

    public static T Create<T>()
    {
        Func<object> func = (from p in Store where p.Key == typeof(T) select p.Value).FirstOrDefault();

        if (func != null) return (T)func();
        return default(T);
    }
}
类工厂
{
私有静态字典存储=新字典();
公共静态无效设置(Func创建)
{
添加(typeof(T),()=>Creation());
}
publicstatict-Create()
{
Func Func=(从存储区中的p开始,其中p.Key==typeof(T)选择p.Value);
如果(func!=null)返回(T)func();
返回默认值(T);
}
}
因此,我们在合成根目录下对其进行如下配置:

Factory.Setup(() => container.Resolve<ITest>());

Factory.Setup<ISomeWcfService>(() => new SomeWcfService());
Factory.Setup(()=>container.Resolve());
Factory.Setup(()=>newsomewcfservice());
最后,要创建一个具体类型:

ITest t = Factory.Create<ITest>();
ISomeWcfService client = Factory.Create<ISomeWcfService>();
ITest t=Factory.Create();
ISomeWcfService client=Factory.Create();
现在问题和想法:

我是不是重新发明了servicelocator模式


我知道传递容器是个坏主意,这样就解决了这个问题,而且它不依赖于容器,但这看起来不错还是仅仅是个坏主意?

我是不是重新发明了servicelocator模式?对这仅仅是个糟糕的主意吗?可能吧,哈哈哈!我仍然没有在应用程序中获取对象实例的最佳方法,我不想传递10个以上的参数,也不想手动维护许多工厂。自动连接DI容器的好处是,如果需要在应用程序中添加深层依赖项,您只需要更改一个类-因为您从未手动调用
new
,所以不需要更改其他类。关于手动维护工厂,您可以将
Func
与Autofac和其他一些容器一起使用。还有,看看吧,这在我看来很不错,“不传递容器引用”。什么意思?你什么时候需要把集装箱运过来?如果你正确地应用了依赖注入原则,你就永远不必“到处传递容器”。那么,如果一个类被实例化,而该类与服务有依赖关系,那么这个实例的创建者是否应该负责传递依赖关系,尽管他可能不需要它?我应该在这里使用工厂吗?