简体   繁体   中英

Using Unity, How do I autoregister a generic class with a generic interface without registering EVERY type to it

I am using Unity and Unity.AutoRegistration . This line for Unity:

unityContainer.RegisterType(typeof(IAction<>), typeof(Action<>));

effectively registers every class in the project to IAction/Action:

unityContainer.RegisterType<IAction<ObjectA>, Action<ObjectA>>();
unityContainer.RegisterType<IAction<ObjectB>, Action<ObjectB>>();
unityContainer.RegisterType<IAction<ObjectC>, Action<ObjectC>>();
[...]
unityContainer.RegisterType<IAction<UnrelatedObject>, Action<UnrelatedObject>>();
[...]

But, I only want specific objects to be registered. How would I do that? My guess is to add a custom attribute decorator to the specific classes.

[ActionAtribute]
public class ObjectB
{ [...] }

And try to use Unity.AutoRegistration . This is where I am stuck at:

unityContainer.ConfigureAutoRegistration()
    .Include(If.DecoratedWith<ActionAtribute>,
             Then.Register()
             .As   ?? // I'm guessing this is where I specify
             .With ?? // IAction<match> goes to Action<match>
             )
    .ApplyAutoRegistration();

Include method has overload that allows you to pass lambda to register your type. To achieve exactly what you want with attributes you can do like this:

        unityContainer.ConfigureAutoRegistration()
            .Include(If.DecoratedWith<ActionAtribute>,
                     (t, c) => c.RegisterType(typeof(IAction<>).MakeGenericType(t), typeof(Action<>).MakeGenericType(t)))
            .IncludeAllLoadedAssemblies()
            .ApplyAutoRegistration();

Also, first argument of Include method is Predicate, so if you don't want to use attributes but some other mechanism to define what types to include or exclude, you can do like this:

        // You may be getting these types from your config or from somewhere else
        var allowedActions = new[] {typeof(ObjectB)}; 
        unityContainer.ConfigureAutoRegistration()
            .Include(t => allowedActions.Contains(t),
                     (t, c) => c.RegisterType(typeof(IAction<>).MakeGenericType(t), typeof(Action<>).MakeGenericType(t)))
            .IncludeAllLoadedAssemblies()
            .ApplyAutoRegistration();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM