Я пытаюсь получить 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
Вот рабочий пример, который отвечает на ваш первый вопрос
[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);
}
LoggingEntityRepository
не реализуетIUserEntityRepository
поэтому не может его украсить. Вы можете заставить его работать как есть, если в своем коде вы называете службуIEntityRepository<User>
.