Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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# Unity:更改隐式注册的默认生存期管理器和/或禁用它们_C#_.net_Dependency Injection_Unity Container - Fatal编程技术网

C# Unity:更改隐式注册的默认生存期管理器和/或禁用它们

C# Unity:更改隐式注册的默认生存期管理器和/或禁用它们,c#,.net,dependency-injection,unity-container,C#,.net,Dependency Injection,Unity Container,Unity容器将自动解析它自己可以识别的任何类型,而无需手动注册。这在某些方面是好的,但我的问题是它使用了一个TransientLifetimeManager来进行这种类型的解析,而我几乎总是想要一个containerControlled LifetimeManager。当然,我仍然可以手动将我的类型注册为Singleton,但是如果我忘记了,在启动时不会得到未处理的异常,应用程序将成功启动,一切都将正常工作。但是最终会有一些bug,可能非常微妙,很难诊断,因为一个类型有多个实例是单例的 所以我

Unity容器将自动解析它自己可以识别的任何类型,而无需手动注册。这在某些方面是好的,但我的问题是它使用了一个
TransientLifetimeManager
来进行这种类型的解析,而我几乎总是想要一个
containerControlled LifetimeManager
。当然,我仍然可以手动将我的类型注册为Singleton,但是如果我忘记了,在启动时不会得到未处理的异常,应用程序将成功启动,一切都将正常工作。但是最终会有一些bug,可能非常微妙,很难诊断,因为一个类型有多个实例是单例的

所以我的问题是:有没有一种方法可以指定不同的默认生存期管理器,或者完全禁用默认的自动解析行为,并将容器限制为我自己注册的类型(直接或按照我自己的约定)

有没有一种方法可以指定不同的默认生存期管理器

是的,您可以使用将使用不同生存期管理器的容器扩展。有关示例,请参见

或者完全禁用默认的自动解析行为,并将容器限制为我自己注册的类型

是的,容器扩展也可以做到这一点

首先在显式注册期间记录注册的BuildKey。然后在创建对象之前检查BuildKey是否已显式注册

public class RegistrationTrackingExtension : UnityContainerExtension
{
    private ConcurrentDictionary<NamedTypeBuildKey, bool> registrations =
        new ConcurrentDictionary<NamedTypeBuildKey, bool>();

    protected override void Initialize()
    {
        base.Context.Registering += Context_Registering;
        base.Context.Strategies.Add(
            new ValidateRegistrationStrategy(this.registrations), UnityBuildStage.PreCreation);
    }

    private void Context_Registering(object sender, RegisterEventArgs e)
    {
        var buildKey = new NamedTypeBuildKey(e.TypeTo, e.Name);
        this.registrations.AddOrUpdate(buildKey, true, (key, oldValue) => true);
    }

    public class ValidateRegistrationStrategy : BuilderStrategy
    {
        private ConcurrentDictionary<NamedTypeBuildKey, bool> registrations; 

        public ValidateRegistrationStrategy(ConcurrentDictionary<NamedTypeBuildKey, bool> registrations)
        {
            this.registrations = registrations;
        }

        public override void PreBuildUp(IBuilderContext context)
        {
            if (!this.registrations.ContainsKey(context.BuildKey))
            {
                Exception e = new Exception("Type was not explicitly registered in the container.");
                throw new ResolutionFailedException(context.BuildKey.Type, context.BuildKey.Name, e, context);
            }
        }
    }
}
公共类注册跟踪扩展:UnityContainerExtension
{
私有ConcurrentDictionary注册=
新的ConcurrentDictionary();
受保护的覆盖无效初始化()
{
base.Context.registing+=Context\u registing;
base.Context.Strategies.Add(
新的ValidateRegistrationStrategy(this.registrations),UnityBuildStage.PreCreation);
}
私有无效上下文\u注册(对象发送方、注册方目标)
{
var buildKey=new NamedTypeBuildKey(e.TypeTo,e.Name);
this.registrations.AddOrUpdate(buildKey,true,(key,oldValue)=>true);
}
公共类验证注册策略:BuilderStrategy
{
私人词典注册;
公共验证注册策略(ConcurrentDictionary注册)
{
这个。注册=注册;
}
公共覆盖无效预构建(IBuilderContext上下文)
{
if(!this.registrations.ContainsKey(context.BuildKey))
{
异常e=新异常(“类型未在容器中显式注册”);
抛出新的ResolutionFailedException(context.BuildKey.Type,context.BuildKey.Name,e,context);
}
}
}
}
然后添加扩展,注册一些类并解析。如果未显式注册该类,则将引发异常

IUnityContainer container = new UnityContainer();
// Add container extension
container.AddNewExtension<RegistrationTrackingExtension>();

// Register types
container.RegisterType<MyClass>();
container.RegisterType<IMyClass, MyClass>();
container.RegisterType<IMyClass, MyClass>("A");

// These succeed because they were explicitly registered
container.Resolve<IMyClass>();
container.Resolve<IMyClass>("A");
container.Resolve<MyClass>();

// MyClass2 was not registered so this will throw an exception
container.Resolve<MyClass2>();
IUnityContainer container=newunitycontainer();
//添加容器扩展名
container.AddNewExtension();
//寄存器类型
container.RegisterType();
container.RegisterType();
容器注册类型(“A”);
//这些成功是因为它们已显式注册
container.Resolve();
集装箱。决议(“A”);
container.Resolve();
//MyClass2未注册,因此将引发异常
container.Resolve();

我尝试了DefaultLifetimeManegerExtension,但不知何故它不起作用。(也许团结已经改变了?)。无论如何,如果您不想使用扩展,也可以使用RegsiterByConvention功能

container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.None, WithName.Default, x => new DisposingTransientLifetimeManager());

这将使用“DisposingTransientLifetimeManager”注册所有类,我选择将其用作默认类。请注意,您应该在注册开始时执行此操作,因为所有注册都将覆盖以前任何相同类型和名称的注册。

可能重复的Great;这似乎给了我一种设置默认
LifetimeManager
的方法。我还想知道是否有办法禁用自动/隐式注册;这两种解决方案都非常有效。而且,
RegistrationTrackingExtension
已经在应用程序中发现了几个错误!