views:

388

answers:

2

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();
A: 

Does the answer here help http://stackoverflow.com/questions/2198982/specifying-a-default-unity-type-mapping-for-a-generic-interface-and-class-pair

Preet Sangha
No. That answer is basically the first line in my question that registers everything. I need a way to register specific classes with IAction/Action without doing it manually.
Jared
oh sorry, didn't realise that.
Preet Sangha
+3  A: 

Hi Jared,

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();
Artem Govorov
That is exactly what I needed! Thank you for the example.
Jared