3

我已经使用 Castle.DynamicProxy 和 StructureMap 2.6 API 进行了拦截,但现在无法使用 StructureMap 3.0 进行拦截。谁能帮我找到更新的文档甚至演示?我发现的一切似乎都与旧版本有关。例如 StructureMap.Interceptors.TypeInterceptor 接口等。

4

2 回答 2

7

哈哈!我他妈的做到了!就是这样:

public class ServiceSingletonConvention : DefaultConventionScanner
{
    public override void Process(Type type, Registry registry)
    {
        base.Process(type, registry);

        if (type.IsInterface || !type.Name.ToLower().EndsWith("service")) return;

        var pluginType = FindPluginType(type);

        var delegateType = typeof(Func<,>).MakeGenericType(pluginType, pluginType);

        // Create FuncInterceptor class with generic argument +
        var d1 = typeof(FuncInterceptor<>);

        Type[] typeArgs = { pluginType };

        var interceptorType = d1.MakeGenericType(typeArgs);
        // -

        // Create lambda expression for passing it to the FuncInterceptor constructor +
        var arg = Expression.Parameter(pluginType, "x");

        var method = GetType().GetMethod("GetProxy").MakeGenericMethod(pluginType);

        // Crate method calling expression
        var methodCall = Expression.Call(method, arg);

        // Create the lambda expression
        var lambda = Expression.Lambda(delegateType, methodCall, arg);
        // -

        // Create instance of the FuncInterceptor
        var interceptor = Activator.CreateInstance(interceptorType, lambda, "");

        registry.For(pluginType).Singleton().Use(type).InterceptWith(interceptor as IInterceptor);
    }

    public static T GetProxy<T>(object service)
    {
        var proxyGeneration = new ProxyGenerator();

        var result = proxyGeneration.CreateInterfaceProxyWithTarget(
           typeof(T),
           service,
           (Castle.DynamicProxy.IInterceptor)(new MyInterceptor())
           );

        return (T)result;
    }
}

这里的问题是 SM 3.* 允许拦截已知类型,即执行以下操作:

expression.For<IService>().Use<Service>().InterceptWith(new FuncInterceptor<IService>(service => GetProxyFrom(service)));

但是,如果您想在自定义扫描约定中包含拦截逻辑,您想拦截具有特定签名的所有类型实例(在我的例子中,类型名称以“服务”结尾)?

这就是我使用 Expression API 和反射所完成的。

另外,我在这里使用 Castle.DinamicProxy 为我的服务创建代理对象。

希望其他人会发现这有帮助:)

于 2014-05-13T21:59:31.340 回答
1

我发现任何新版本的最佳去处是直接访问源代码。

如果写得好,那么它将包括测试用例。值得庆幸的是,结构图确实包含测试用例。

你可以在这里探索测试

同时,我已经编写了一个 Activator Interceptor 的示例,以及如何配置它。

static void Main()
{
    ObjectFactory.Configure(x =>
    {
        x.For<Form>().Use<Form1>()
            .InterceptWith(new ActivatorInterceptor<Form1>(y =>  Form1Interceptor(y), "Test"));
    });
    Application.Run(ObjectFactory.GetInstance<Form>());

}

public static void Form1Interceptor(Form f)
{
    //Sets the title of the form window to "Testing"
    f.Text = "Testing";
}

编辑:

如何使用“全局”过滤器PoliciesExpression

[STAThread]
static void Main()
{
    ObjectFactory.Configure(x =>
    {
        x.Policies.Interceptors(new InterceptorPolicy<Form>(new FuncInterceptor<Form>(y => Intercept(y))));
    });
    Application.Run(ObjectFactory.GetInstance<Form>());
}

private static Form Intercept(Form form)
{
    //Do the interception here
    form.Text = "Testing";
    return form;
}
于 2014-05-11T22:58:25.157 回答