Вопрос

I have the following code:

_container = new Container(x => x.AddRegistry<ManagerRegistry>());

-

public class ManagerRegistry : Registry
{
    public ManagerRegistry()
    {
        var proxyGenerator = new ProxyGenerator();

        For<IPersonManager>()
            .EnrichAllWith(t => proxyGenerator.CreateInterfaceProxyWithTarget(
                                t, new AuthenticationInterceptor()))
            .Use<PersonManager>();
    }
}

-

public class AuthenticationInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (!HttpContext.Current.User.IsInRole("Monkey"))
            throw new Exception("Only monkeys allowed!");

        invocation.Proceed();
    }
}

It interceps the creation of a dependency in StructureMap, and decorates it using DynamicProxy.
Now this works fine, because the interceptor has no dependencies itself.

But given the following:

public class LoggingInterceptor : IInterceptor
{
    public LoggingInterceptor(ILogger logger)
    {

How would I go about wiring that up in StructureMap?

Это было полезно?

Решение

This is what I came up with:

_container.RegisterInterceptor<IPersonManager, LoggingInterceptor>();

-

public static class ContainerExtensions
{
    public static void RegisterInterceptor<TDependency, TInterceptor>(this IContainer container)
        where TDependency : class
        where TInterceptor : IInterceptor 
    {
        IInterceptor interceptor = container.GetInstance<TInterceptor>();

        if (interceptor == null)
            throw new NullReferenceException("interceptor");

        TypeInterceptor typeInterceptor 
            = new GenericTypeInterceptor<TDependency>(interceptor);

        container.Configure(c => c.RegisterInterceptor(typeInterceptor));
    }
}

-

public class GenericTypeInterceptor<TDependency> : TypeInterceptor
    where TDependency : class
{
    private readonly IInterceptor _interceptor;
    private readonly ProxyGenerator _proxyGenerator = new ProxyGenerator();

    public GenericTypeInterceptor(IInterceptor interceptor)
    {
        if (interceptor == null)
            throw new ArgumentNullException("interceptor");

        _interceptor = interceptor;
    }

    public object Process(object target, IContext context)
    {
        return _proxyGenerator.CreateInterfaceProxyWithTarget(target as TDependency, _interceptor);
    }

    public bool MatchesType(Type type)
    {
        return typeof(TDependency).IsAssignableFrom(type);
    }
}

I'm pretty happy with the result.

Другие советы

I can be completely wrong here, but doesn't this do the trick?

For<IPersonManager>()
    .EnrichAllWith(t => proxyGenerator.CreateInterfaceProxyWithTarget(
        t, _container.GetInstance<AuthenticationInterceptor>()))
    .Use<PersonManager>();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top