Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.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# 简易注射器防止容器锁死_C#_Dependency Injection_Simple Injector - Fatal编程技术网

C# 简易注射器防止容器锁死

C# 简易注射器防止容器锁死,c#,dependency-injection,simple-injector,C#,Dependency Injection,Simple Injector,我需要知道调用GetInstance后是否有方法防止容器锁定 我在MediaInstanceFactory中有一个实现,其中T:Xamarin.Forms.Page,我需要在字符串和特定的具体类型之间建立关联。不幸的是,为了让它工作,我必须在所有注册完成之前在MediaInstanceFactory中解析 如何防止容器被锁定 编辑: 我们从如下扩展开始: public static void RegisterPage<T>(this Container container, stri

我需要知道调用
GetInstance
后是否有方法防止容器锁定

我在MediaInstanceFactory中有一个实现,其中T:Xamarin.Forms.Page,我需要在字符串和特定的具体类型之间建立关联。不幸的是,为了让它工作,我必须在所有注册完成之前在MediaInstanceFactory中解析

如何防止容器被锁定

编辑: 我们从如下扩展开始:

public static void RegisterPage<T>(this Container container, string name)
    where T : Page
{
   // Do Platform stuff
   var namedInstance = continer.GetInstance<INamedInstanceFactory<Page>>();
   var namedInstance.Register( typeof( T ), name, Lifestyle.Transient );
}

简易注射器在首次使用后锁定容器,不允许容器解锁。这种行为是非常故意的,并且详细解释了为什么在解决问题后进行注册是个坏主意。在解析后进行注册是一种反模式,有时被称为寄存器解析寄存器(不要与混淆)

虽然Simple Injector从第一天起就有了这种设计,但其他DI容器维护人员也意识到了这一点,您会看到越来越多的DI容器进入了一个严格的模型中,在容器构建或第一次解决后,容器不能被更改

Simple Injector对此非常严格,因为-不仅会导致寄存器解析寄存器模式弊大于利,还必须认识到,始终有一种更干净的方法来设计和编写代码,这样就不需要应用寄存器解析寄存器。然而,这通常需要一些详细的信息来说明你想要完成什么,这就是为什么我坚持要获得更多信息的原因

开发人员被引诱进入Register-Resolve-Register反模式的原因之一是,他们被误导,认为使用
new
创建类是一种罪恶,并且只允许容器创建实例

然而,这种想法是错误的。尽管让容器自动连接类型对您是有益的,但只要组件(包含行为的应用程序类)是在内部创建的,容器是否创建它们,或者您是否手动创建它们(也称为)并不重要

在某些情况下,手动创建对象或对象图的一部分是有意义的,在某些情况下,这甚至会导致更易于维护的代码,因为容器特别适合构建组成简单对象图的大型对象集。当一个对象图得到一个复杂的结构时,这会使您的DI配置变得非常复杂,在这种情况下,对于对象图的特定部分,返回到纯DI是非常有帮助的。但我离题了

在您的例子中,因为
NamedInstanceFactory
工厂是一个简单的单例。它只引用了
容器
,它也是一个单例,这样的工厂也不太可能得到其他依赖项,或者应该有不同的生活方式。这意味着不需要从容器中解析它(虽然在理论上您仍然可以在不引起Register resolve Register的情况下解析它,但我们不要这样做),即使这种类型是泛型的

如果我没有弄错的话,以下注册将有效地解决您的问题:

var pageFactory = new NamedInstanceFactory<Page>(Container);
Container.RegisterSingleton<INamedInstanceFactory<Page>>(pageFactory);

pageFactory.RegisterType(typeof(StartPage), Lifestyle.Singleton);
pageFactory.RegisterType(typeof(UserDetailsPage), Lifestyle.Transient);
pageFactory.RegisterType(typeof(SomeOtherPage), Lifestyle.Transient);
var pageFactory=newnamedinstancefactory(容器);
集装箱登记单(pageFactory);
pageFactory.RegisterType(typeof(StartPage),Lifestyle.Singleton);
RegisterType(typeof(UserDetailsPage),lifesture.Transient);
pageFactory.RegisterType(typeof(SomeOtherPage),lifesture.Transient);
尽管可以让容器自动连接
NamedInstanceFactory
(即使使用开放的通用注册),但我严重怀疑这样的事情是否会使解决方案比这里介绍的更简单


如果您感兴趣,前面提供的在底部有一段解释如何延迟添加注册。

请在您的问题中添加更多详细信息,以便我们可以分析您需要执行注册解析注册的根本原因。@Steven这是反模式的一部分,正如我前面提到的,我需要跟踪具体类型,但也有一些实例需要能够为命名实例指定特定的生活方式。在页面的情况下没有那么多,但是有一个框架服务。嗨,丹,我真的帮不了你,因为我的信息太少了。正如我所说的,需要更多的信息(显示代码,这在MedinrTanceFactory中是什么,它有什么依赖关系,与字符串和具体类型有什么关联,为什么它在这里很重要。show cod)@Steven根据要求,我添加了完整的代码示例。对于显示的示例,它将是
container.getInstance这当然有效。我只是不喜欢这样一个事实,即我必须在静态上下文中执行此操作,因为我将它作为扩展方法的一部分公开。@DanS.:防止为此使用扩展方法,或者在扩展方法中作为方法参数传入所需的依赖项。
Container.Register(typeof(INamedInstanceFactory<>), typeof(NamedInstanceFactory<> ), 
    Lifestyle.Singleton);
public Page CreatePage(string name)
{
    return namedInstanceFactory.CreateNew(name);
}
var pageFactory = new NamedInstanceFactory<Page>(Container);
Container.RegisterSingleton<INamedInstanceFactory<Page>>(pageFactory);

pageFactory.RegisterType(typeof(StartPage), Lifestyle.Singleton);
pageFactory.RegisterType(typeof(UserDetailsPage), Lifestyle.Transient);
pageFactory.RegisterType(typeof(SomeOtherPage), Lifestyle.Transient);