我使用Castle.DynamicProxy和StructureMap 2.6 API进行了拦截,但现在无法使用StructureMap 3.0进行拦截。谁能帮我找到更新的文档甚至演示?我发现的一切似乎与旧版本有关。例如StructureMap.Interceptors.TypeInterceptor接口等。
答案 0 :(得分:7)
HAHAA!我做了!方法如下:
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)));
但是,如果您想在自定义扫描约定中包含拦截逻辑,并且要拦截具有特定签名的所有类型实例(在我的情况下名称以'service'结尾的类型),该怎么办?
这就是我使用Expression API和反射完成的。
另外,我在这里使用Castle.DinamicProxy为我的服务创建代理对象。
希望其他人会发现这有用:)
答案 1 :(得分:0)
我发现任何新版本的最佳位置都是直接来源。
如果写得好,那么它将包括测试用例。值得庆幸的是,structuremap确实包含测试用例。
您可以浏览测试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";
}
编辑:
如何使用&#34;全球&#34;使用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;
}