Unity: changing the default manager for implicit registrations by default and / or disabling them

The Unity container will automatically allow any type that it can determine on its own, without the need for manual registration. In some ways this is good, but the problem is that TransientLifetimeManager used for this type of permission, and I almost always want ContainerControlledLifetimeManager . Of course, I can register my types as single games manually, but if I forget, instead of getting an incomplete exception at startup, the application will start successfully and everything will work. But in the end there will be errors, possibly very subtle, difficult to diagnose, due to the fact that there are several instances of a type that must be singleton.

So my question is: is there a way to specify another default manager by default, or completely disable the default automatic resolution behavior and restrict the container to types that I register myself (directly or by my own conventions)?

+8
c # dependency-injection unity-container
source share
2 answers

Is there a way to specify a different default life manager

Yes, you can use a container extension that another lifetime manager will use. For an example, see Requesting a Custom Standard lifetimemanager .

or completely disable the default automatic resolution behavior and restrict the container to the types that I register myself

Yes, container extension can also do this.

First, during the explicit registration record of the BuildKey registration. Then, before creating the object, check if there was an explicit BuildKey registration.

 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); } } } } 

Then add the extension, register some classes and decide. If the class has not been explicitly registered, an exception is thrown.

 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>(); 
+5
source share

I tried DefaultLifetimeManegerExtension, but somehow it didn't work. (Maybe Unity has changed?). In any case, if you do not want to use the extension, you can also use the RegsiterByConvention function.

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

This will register all classes with the "DisposingTransientLifetimeManager", which I decided to use as standard. Please note that you must do this at the beginning of your registrations, as all registrations will overwrite any previous registrations of the same type and name.

+1
source share

All Articles