Disable Auto Registration

Nov 4, 2014 at 11:38 AM
Hi,

Is it possible to disable autoregistration in Unity 3.5? How can I configure that?

I'd like to make sure that only types which are explicitly registered could be resolved.

Thanks,
Martin
Nov 6, 2014 at 2:43 AM
Edited Nov 6, 2014 at 2:45 AM
I assume you are not discussing auto-registration in the sense of registration by convention (since that is an easy feature to not use). Instead I assume that you mean that you don't want just any type being resolved since Unity can resolve concrete types without them being registered. For example the following code will succeed without any registrations:
IUnityContainer container = new UnityContainer();
container.Resolve<MyClass>();
If we want to force every type to be registered before being resolved then you could do that with a container extension:
public class MandatoryRegistrationExtension : UnityContainerExtension
{
    private RegistrationValidationStrategy strategy;

    protected override void Initialize()
    {
        this.Context.Registering += Context_Registering;
        this.strategy = new RegistrationValidationStrategy(Container);
        Context.Strategies.Add(this.strategy, UnityBuildStage.PreCreation);
    }

    private void Context_Registering(object sender, RegisterEventArgs e)
    {            
        this.strategy.AddRegisteredType(e.TypeTo, e.Name);
    }

    private class RegistrationValidationStrategy : BuilderStrategy
    {
        private const byte dummy = 0;
        private readonly IUnityContainer container;
        private readonly ConcurrentDictionary<NamedTypeBuildKey, byte> registeredTypes = new ConcurrentDictionary<NamedTypeBuildKey, byte>();

        public RegistrationValidationStrategy(IUnityContainer container)
        {
            this.container = container;
        }

        public void AddRegisteredType(Type type, string name)
        {
            NamedTypeBuildKey buildKey = new NamedTypeBuildKey(type, name);
            this.registeredTypes.AddOrUpdate(buildKey, dummy, (k,v) => dummy);
        }

        public override void PreBuildUp(IBuilderContext context)
        {
            byte val;
            if (!this.registeredTypes.TryGetValue(context.BuildKey, out val))
            {
                throw new Exception("Type not registered");
            }
        }
    }
}

Then we can add the extension:
IUnityContainer container = new UnityContainer();
container.AddNewExtension<MandatoryRegistrationExtension>();
Now the following code will succeed:
IUnityContainer container = new UnityContainer();
container.AddNewExtension<MandatoryRegistrationExtension>();

container.RegisterType<MyClass>();
container.RegisterType<IText, Text>();

container.Resolve<IText>();
container.Resolve<MyClass>();

However, the following will throw an exception since the name does not match the registration:
container.Resolve<IText>("A");
// Also this will throw since it was not registered:
container.Resolve<AnotherClass>();
If you don't care about name and only if the specific type was registered then you can just set the name to null in the above code.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by martin_weber on 11/5/2014 at 10:01 PM
Nov 6, 2014 at 6:05 AM
Thank you so much Randy.
Yes, this is exactly what I want to do.