Dependency injection 使用StructureMap 3进行拦截*

Dependency injection 使用StructureMap 3进行拦截*,dependency-injection,inversion-of-control,ioc-container,interception,structuremap3,Dependency Injection,Inversion Of Control,Ioc Container,Interception,Structuremap3,我已经使用Castle.DynamicProxy和StructureMap 2.6 API进行了拦截,但现在无法使用StructureMap 3.0进行拦截。有人能帮我找到更新的文档甚至是演示吗?我发现的一切似乎都是关于旧版本的。e、 g.StructureMap.Interceptors.TypeInterceptor接口等。我发现任何新版本的最佳选择都是直接指向源代码 如果它写得好,那么它将包括测试用例。谢天谢地,structuremap确实包含测试用例 您可以浏览这些测试 同时,我还编写了

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

我发现任何新版本的最佳选择都是直接指向源代码

如果它写得好,那么它将包括测试用例。谢天谢地,structuremap确实包含测试用例

您可以浏览这些测试

同时,我还编写了一个Activator拦截器的示例,以及如何配置它

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";
}

哈哈!是我干的!以下是方法:

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;
    }
}
公共类服务SingletonConvention:DefaultConventionScanner
{
公共重写无效进程(类型,注册表)
{
进程(类型、注册表);
if(type.IsInterface | | |!type.Name.ToLower().EndsWith(“服务”))返回;
var pluginType=FindPluginType(类型);
var delegateType=typeof(Func).MakeGenericType(pluginType,pluginType);
//使用泛型参数创建FuncInterceptor类+
var d1=类型(截取器);
Type[]typeArgs={pluginType};
var interceptorType=d1.MakeGenericType(typeArgs);
// -
//创建lambda表达式以将其传递给FuncInterceptor构造函数+
var arg=Expression.Parameter(pluginType,“x”);
var method=GetType().GetMethod(“GetProxy”).MakeGenericMethod(pluginType);
//板条箱方法调用表达式
var methodCall=Expression.Call(方法,arg);
//创建lambda表达式
var lambda=Expression.lambda(delegateType,methodCall,arg);
// -
//创建FuncInterceptor的实例
var interceptor=Activator.CreateInstance(interceptorType,lambda,“”);
registry.For(pluginType).Singleton().Use(type).InterceptWith(interceptor作为IInterceptor);
}
公共静态T GetProxy(对象服务)
{
var proxyGeneration=新的ProxyGenerator();
var result=proxyGeneration.CreateInterfaceProxyWithTarget(
类型(T),
服务
(Castle.DynamicProxy.IInterceptor)(新的MyInterceptor())
);
返回(T)结果;
}
}
这里的问题是SM 3.*允许拦截已知类型,即执行以下操作:

expression.For<IService>().Use<Service>().InterceptWith(new FuncInterceptor<IService>(service => GetProxyFrom(service)));
expression.For().Use().InterceptWith(新的FuncInterceptor(服务=>GetProxyFrom(服务));
但是,如果您希望在自定义扫描约定中包含拦截逻辑,您希望拦截具有特定签名的类型的所有实例(在我的例子中,类型的名称以“service”结尾),该怎么办

这就是我使用表达式API和反射所完成的

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


希望其他人会觉得这很有帮助:)

非常感谢。但我要寻找的是一种允许我使用Castle动态代理拦截方法调用的方法。我还希望将其用于几个接口,例如,用于给定程序集中的所有服务。现在,我正在使用我自己的约定扫描器,并希望在其中添加拦截逻辑。类似这样的内容:registry.For(pluginType).Singleton().Use(type).Intercept(..等等,在SM2上发布你的旧工作代码,也许我可以进一步提供帮助。基本上,我是在SM2中通过调用ConfigurationExpression.RegisterInterceptor方法实现的,这需要简单的TypeInterceptor实例。经过数小时的努力,我发现我想要的是类似于FuncInterceptor的东西,如果我我不想截取一种特定的插件类型,例如,而不是像这样的东西:registry.for().Use().InterceptWith(新的FuncInterceptor(blabla));我想在DefaultConventionScanner中做同样的事情,也就是说,动态地,在不知道确切类型的情况下,我看到这意味着要编写一些新IInterceptor的自定义实现,这将在内部实现表达式重载。但是我还不太熟悉表达式的概念,必须进行很多努力。难道他们就不能添加一个简单的截取方法,只需要一个简单的lambda表达式来调整插入的实例。。。
expression.For<IService>().Use<Service>().InterceptWith(new FuncInterceptor<IService>(service => GetProxyFrom(service)));