Используя Unity, Как мне автоматически зарегистрировать универсальный класс с универсальным интерфейсом, не регистрируя КАЖДЫЙ тип в нем - PullRequest
6 голосов
/ 12 февраля 2010

Я использую Unity и Unity.AutoRegistration . Эта строка для Unity:

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

эффективно регистрирует каждый класс в проекте для 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>>();
[...]

Но я хочу, чтобы только определенные объекты были зарегистрированы. Как бы я это сделал? Я предполагаю добавить собственный декоратор атрибутов для определенных классов.

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

И попробуйте использовать Unity.AutoRegistration . Вот где я застрял:

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

1 Ответ

6 голосов
/ 16 февраля 2010

Метод include имеет перегрузку, которая позволяет передавать лямбду для регистрации вашего типа. Для достижения именно того, что вы хотите с атрибутами, вы можете сделать так:

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

Кроме того, первым аргументом метода Include является Predicate, поэтому, если вы не хотите использовать атрибуты, а используете какой-то другой механизм для определения того, какие типы включать или исключать, вы можете сделать так:

        // 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();
...