Структура карты3 Украсить все

1

Я пытаюсь получить DecorateAllWith для работы с общими интерфейсами. Я прочитал несколько сообщений здесь, где они решили это с помощью перехватчиков, но они, похоже, используют более раннюю версию структуры структуры, и это не похоже на "чистое" решение.

Мне действительно нужна помощь, чтобы заставить его работать со структурой карты 3

У меня есть общий репозиторий, который я бы хотел украсить как протоколированием, так и кэшированием

public interface IEntityRepository<T> where T : Entities.IEntity
{
}

У меня есть около 20 интерфейсов, которые наследуют IEntityRepository. Пример mu UserRepository

public interface IUserEntityRepository : IEntityRepository<User>
{
}

И тогда у меня есть конкретный тип оформления logging, который бы хотел, чтобы все экземпляры IEntityRepository были украшены

public class LoggingEntityRepository<T> : IEntityRepository<T> where T : Entities.IEntity
{
    private readonly IEntityRepository<T> _repositoryDecorated;

    public LoggingEntityRepository(IEntityRepository<T> repositoryDecorated)
    {
        _repositoryDecorated = repositoryDecorated;
    }
}

Или существуют ли другие контейнеры IoC, лучше подходящие для того, что я пытаюсь выполнить?

Изменить: есть ли способ украсить все интерфейсы, которые наследуются от IEntityRepository

Теги:
decorator
structuremap3

1 ответ

1
Лучший ответ

Вот рабочий пример, который отвечает на ваш первый вопрос

[Fact]
public void DecorateAllWith_AppliedToGenericType_IsReturned()
{
    var container = new Container(registry =>
    {
        registry.Scan(x =>
        {
            x.TheCallingAssembly();
            x.ConnectImplementationsToTypesClosing(typeof(IEntityRepository<>));

        });

        registry.For(typeof(IEntityRepository<>))
            .DecorateAllWith(typeof(LoggingEntityRepository<>));
    });

    var result = container.GetInstance<IEntityRepository<Entity1>>();

    Assert.IsType<LoggingEntityRepository<Entity1>>(result);
}

Чтобы ответить на ваш второй вопрос, я лично использую (и способствую) Простой инжектор - это один из самый быстрый контейнер, имеет всестороннюю поддержку generics и предлагает несколько мощных diagnostic.

Регистрация в Simple Injector будет выглядеть так:

[Fact]
public void RegisterDecorator_AppliedToGenericType_IsReturned()
{
    var container = new SimpleInjector.Container();

    container.RegisterManyForOpenGeneric(
        typeof(IEntityRepository<>), 
        typeof(IEntityRepository<>).Assembly);

    container.RegisterDecorator(
        typeof(IEntityRepository<>), 
        typeof(LoggingEntityRepository<>));

    var result = container.GetInstance<IEntityRepository<Entity1>>();

    Assert.IsType<LoggingEntityRepository<Entity1>>(result);
}
  • 0
    Спасибо за Ваш ответ. Мне удалось заставить это работать. Однако, если я пытаюсь получить экземпляр IUserEntityRepository, который не будет работать. Есть ли способ сделать это? Se мой обновленный пост
  • 0
    LoggingEntityRepository не реализует IUserEntityRepository поэтому не может его украсить. Вы можете заставить его работать как есть, если в своем коде вы называете службу IEntityRepository<User> .
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню