使用 StructureMap 3.* 拦截
Posted
技术标签:
【中文标题】使用 StructureMap 3.* 拦截【英文标题】:Interception Using StructureMap 3.* 【发布时间】:2014-06-28 22:09:29 【问题描述】:我已经使用 Castle.DynamicProxy 和 StructureMap 2.6 API 进行了拦截,但现在无法使用 StructureMap 3.0 进行拦截。谁能帮我找到更新的文档甚至演示?我发现的一切似乎都与旧版本有关。例如StructureMap.Interceptors.TypeInterceptor 接口等
【问题讨论】:
【参考方案1】:哈哈哈!我他妈的做到了!方法如下:
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 为我的服务创建代理对象。
希望其他人会觉得这很有帮助:)
【讨论】:
【参考方案2】:我发现任何新版本的最佳去处是直接访问源代码。
如果写得好,那么它将包含测试用例。幸好结构图确实包含测试用例。
您可以探索测试here
与此同时,我已经编写了一个 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;
【讨论】:
非常感谢。但我正在寻找的是一种允许我使用 Castle Dynamic Proxy 拦截方法调用的方法。而且我还想将它用于多个接口,例如对于给定程序集中的所有服务。现在我正在使用我自己的约定扫描器,并想在其中添加拦截逻辑。像这样:registry.For(pluginType).Singleton().Use(type).Intercept(....等等 使用 SM2 发布您的旧工作代码,也许我可以提供进一步的帮助。 基本上我在 SM2 中通过调用 ConfigurationExpression.RegisterInterceptor 方法来做到这一点,这需要简单的 TypeInterceptor 实例。经过数小时的努力,我发现我想要的是类似于 FuncInterceptor 的东西,如果我只是想要对一种特定的插件类型进行拦截 即而不是这样的:registry.For以上是关于使用 StructureMap 3.* 拦截的主要内容,如果未能解决你的问题,请参考以下文章
使用 PetaPoco 与 StructureMap 的共享连接