Structuremap3 DecorateAllWith

試著忘記壹切 提交于 2019-12-11 09:07:02

问题


I've been struggling getting DecorateAllWith working on generic interfaces. I've read some posts here where they solved it using interceptors but they seem to be using an older structure map version and it doesn't seem like a "clean" solution.

I would really need some help to get it working with structure map 3

I have a generic repository which i would like to decorate with both logging and caching

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

I have about 20 interfaces that inherit IEntityRepository. Example mu UserRepository

public interface IUserEntityRepository : IEntityRepository<User>
{
}

And then I have the logging decorator concrete type which I would like all instances of IEntityRepository to be decorated with

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

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

Or are there other IoC containers better suited for what I am trying to accomplish?

Edit: Is there a way to decorate all interfaces that inherit from IEntityRepository


回答1:


Here's a working example that answers your first question

[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);
}

To answer your second question, I personally use (and contribute to) Simple Injector - it is one of the fastest containers available, has comprehensive support for generics and offers some powerful diagnostic services.

The registrations in Simple Injector would look like this:

[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);
}


来源:https://stackoverflow.com/questions/25134096/structuremap3-decorateallwith

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!