TypeInterceptor replacement for Structuremap 3

时间秒杀一切 提交于 2019-12-12 05:13:43

问题


Can't seem to find any useful guide on how to reproduce the functionality currently provided by a TypeInterceptor in my codebase when upgrading from StructureMap 2 to version 3 (can't upgrade to v4 as we aren't using .NET 4.6 yet).

Essentially what the interceptor does is this:

public class TheInterceptor : TypeInterceptor
{
    private Dictionary<string, string> typesToIntercept;

    public TheInterceptor(IDictionary<string, string> typesToIntercept)
    {
        // Passed in on ctor, comes from XML configuration section.
        this.typesToIntercept = typesToIntercept;
    }

    public object Process(object target, StructureMap.IContext ctx)
    {
        var typedTarget = target as BaseType;
        var key = target.GetType().FullName;

        if (typedTarget == null || !typesToIntercept.ContainsKey(key))
        {
            return target;
        }

        var propertyOverrideType = typesToIntercept[key];

        typedTarget.BaseProperty = ctx.GetInstance<IBaseInterface>(propertyOverrideType);

        return typedTarget;
    }
}

So we're basically maintaining a dictionary where the key is the type we want to intercept and the value is a specific type that implements a known interface, that we want to set on a property of the intercepted object.

FWIW I didn't write the original code, I just can't figure out what the correct way of mirroring this behaviour in StructureMap 3 would be. I feel like it's something that could be done without an interceptor, but I believe it was implemented like this so that this behaviour could be used across multiple sites (it's in a shared library) without each site having to explicitly deal with the interception behaviour, so if possible I would like to retain this usage.


回答1:


So I eventually figured this out by trial-and-error. What you need is an ActivatorInterceptor and use the Action delegate to perform the logic that previously would have been inside the Process method of the TypeInterceptor. So from my code snippet above, it becomes:

public class InterceptorPolicy : IInterceptorPolicy
{
    private readonly IDictionary<string, string> typesToIntercept;

    public InterceptorPolicy(IDictionary<string, string> types)
    {
        this.typesToIntercept = types;
    }

    public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance)
    {
        if (instance.ReturnedType.IsSubclassOf(typeof(BaseType)))
        {
            yield return new ActivatorInterceptor<BaseType>((ctx, x) => this.Activate(ctx, x));
        }
    }

    private void Activate(IContext ctx, BaseType instance)
    {
        var key = instance.GetType().FullName;

        if (this.typesToIntercept.ContainsKey(key))
        {
            var propertyOverrideType = this.typesToIntercept[key];

            instance.BaseProperty = ctx.GetInstance<IBaseInterface>(propertyOverrideType);
        }
    }
}


来源:https://stackoverflow.com/questions/36815124/typeinterceptor-replacement-for-structuremap-3

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