城堡动态代理+ Ninject作为DI的问题
本文关键字:DI 问题 作为 Ninject 动态 代理 城堡 | 更新日期: 2023-09-27 18:04:20
我试图为我的项目构建良好的体系结构,我决定使用Ninject
作为DI和Castle project
dinamic proxy
为我的存储库添加缓存。不幸的是,我得到了一个例外。下面是我的代码:
public class NinjectImplementation : NinjectModule
{
public override void Load()
{
// Binding repositories
var assembly = Assembly.GetAssembly(typeof(UserRepository));
var types = assembly.GetTypes()
.Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I"));
ProxyGenerator generator = new ProxyGenerator();
//CacheInterceptor cacheInterceptor =
foreach (var type in types)
{
var interfaceType = type.GetInterfaces().Single();
var typeWithCaching = generator.CreateClassProxy(type, new MyTestShop.Infrastructure.Caching.CacheInterceptor());
Bind(interfaceType).To(typeWithCaching.GetType()).InThreadScope();
}
...//Service layer injection
}
}
所以我注入的不是我的仓库的实现,而是仓库的代理类(带缓存)。
这是我的IInterceptor
实现Castle dinamic proxy
:
[Serializable]
public class CacheInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
int argumentCount = invocation.Arguments.Length;
if (argumentCount > 1)
{
invocation.Proceed();
return;
}
String methodNameInLower = invocation.Method.Name.ToLower();
if (methodNameInLower.StartsWith("get"))
{
String cachePath = invocation.TargetType.FullName + "_" + invocation.Method.Name + "_" + invocation.Arguments[0].ToString();
CacheHelper.Get(cachePath);
//DO SOMETHING
return;
}
}
}
我在Ninject DI container
的_kernel.Get<T>()
方法中得到的异常:
使用条件隐式自绑定激活IInterceptor时出错*
激活路径:3)在UserRepositoryProxy类型的构造函数的参数中注入依赖IInterceptor2)将依赖IUserRepository注入到UserService类型构造函数的userRepository参数中1)请求IUserService
建议:1)确保提供者正确处理创建请求。
描述:当前web请求执行过程中出现未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源位置的更多信息。
Exception Details: Ninject。ActivationException:使用IInterceptor的条件隐式自绑定激活IInterceptor时出错提供程序返回null。激活路径:3)在UserRepositoryProxy类型的构造函数的参数中注入依赖IInterceptor2)将依赖IUserRepository注入到UserService类型构造函数的userRepository参数中1)请求IUserService
建议:1)确保提供者正确处理创建请求。
我终于找到了问题的答案。问题是,我的代理不是一个类型,但类型的实例,所以我修复它像这样:
var interfaceType = type.GetInterfaces().Single();
var proxy = generator.CreateClassProxy(type,
new Type[] { interfaceType },
new IInterceptor[]
{
new CacheInterceptor(),
new LoggingInterceptor()
});
// I'm using directive ToConstant(..), and not To(..)
Bind(interfaceType).ToConstant(proxy).InThreadScope();