Вложенное разрешение - PullRequest
       0

Вложенное разрешение

0 голосов
/ 07 февраля 2011

Скажите, что у меня есть:

ProductA
ProductB

ProductScreen

ProductAScreen1 : ProductScreen
ProductAScreen2 : ProductScreen

ProductBScreen1 : ProductScreen
ProductBScreen2 : ProductScreen

Как я могу настроить его так, чтобы я регистрировал экраны локально для продукта?Поэтому, когда я нахожусь в ProductA и передаю IEnumerable, он не разрешает экраны ProductB?

Я думал, что этого можно достичь, используя что-то вроде объема жизни, но не похоже, что я правильно понял.

1 Ответ

4 голосов
/ 08 февраля 2011

Область действия времени жизни используется для управления временем жизни экземпляра.Вы говорите об управлении отбором.Для этого вам нужно взглянуть на функции метаданных в Autofac.

Используя метаданные, вы можете «пометить» каждый экран товара, указывая, к какому товару он относится:

builder.Register(c => new ProductAScreen1()).As<ProductScreen>()
    .WithMetadata<IProductScreenMetadata>(m =>
        m.For(am => am.ProductType, typeof(ProductA)));
builder.Register(c => new ProductAScreen2()).As<ProductScreen>()
    .WithMetadata<IProductScreenMetadata>(m =>
        m.For(am => am.ProductType, typeof(ProductA)));

builder.Register(c => new ProductBScreen1()).As<ProductScreen>()
    .WithMetadata<IProductScreenMetadata>(m =>
        m.For(am => am.ProductType, typeof(ProductB)));
builder.Register(c => new ProductBScreen2()).As<ProductScreen>()
    .WithMetadata<IProductScreenMetadata>(m =>
        m.For(am => am.ProductType, typeof(ProductB)));

Далее вы можете получить зависимость от IEnumerable<Lazy<ProductScreen, IProductScreenMetadata>> и разрешить экраны в соответствии с типом продукта:

var productScreens = _screens.WHere(a => a.Metadata.ProductType == typeof(ProductA));

Обновление: для полноты, вот более простое решение с использованием Ключевой подход .Во-первых, регистрация намного проще:

builder.RegisterType<ProductAScreen1>().Keyed<ProductScreen>(typeof(ProductA));
builder.RegisterType<ProductAScreen2>().Keyed<ProductScreen>(typeof(ProductA));
builder.RegisterType<ProductBScreen1>().Keyed<ProductScreen>(typeof(ProductB));
builder.RegisterType<ProductBScreen2>().Keyed<ProductScreen>(typeof(ProductB));

Чтобы разрешить набор служб с ключами, нам потребуется зависимость от типа IIndex<,>:

public class SomeService    
{
    private IEnumerable<ProductScreen>> _screens;
    public SomeService(IIndex<Type, IEnumerable<ProductScreen>> screens)
    {
        _screens = screens;
    }

    public void DoSomething()
    {
        var screensForProductA = _screens[typeof(ProductA)];
    }
}

Примечание: для любопытных: вместо жесткого кодирования регистрации типов, вот как вы можете сделать регистрацию «по соглашению»:

var assembly = ...;
var productTypes = ...;  // a collection of all the product types

foreach(var productType in productTypes)
{
    builder.RegisterAssemblyTypes(assembly)
        .Where(t => typeof(ProductScreen).IsAssignableFrom(t))
        .Where(t => t.Name.StartsWith(productType.Name))
        .Keyed<ProductScreen>(productType);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...