我在公共库中使用依赖项解析器接口作为抽象。这使我可以灵活地切换容器。鉴于接口和下面的静态IoC类,我需要使用工厂初始化IoC,而不是从全局asax传递IKernel
。
请参阅下文,了解我如何使用NinjectHttpApplication
库创建Ninject内核。
这是问题所在; IKernel
中的CtsDependencyFactory
属性始终为null
。
Ninject不会像这样注射自己吗?我应该使用不同的方法将IKernel
传递给工厂吗?我在Ninject的ObjectFactory
中找不到像StructureMap
这样的静态类来获取对解析器的引用。
感谢任何帮助。
public interface IResolveDependency
{
T Resolve<T>();
T Resolve<T>(params object[] parameters);
T Resolve<T>(string name);
T Resolve<T>(string name, params object[] parameters);
object Resolve(Type type);
IEnumerable<T> ResolveAll<T>();
void Clear();
}
public interface IResolveDependencyFactory
{
IResolveDependency CreateInstance();
}
public class CtsDependencyResolver : IResolveDependency
{
private readonly IKernel m_kernel;
public CtsDependencyResolver(IKernel kernel)
{
m_kernel = kernel;
}
#region Implementation of IResolveDependency
// removed for brevity
#endregion
}
public class CtsDependencyFactory : IResolveDependencyFactory
{
[Inject]
public IKernel Kernel { get; set; }
#region Implementation of IResolveDependencyFactory
public IResolveDependency CreateInstance()
{
return new CtsDependencyResolver(Kernel);
}
#endregion
}
public static class IoC
{
public static IResolveDependency DependencyResolver { get; private set; }
public static void InitilizeWith(IResolveDependencyFactory factory)
{
DependencyResolver = factory.CreateInstance();
}
public static void Register<T>(T instance)
{
if (DependencyResolver is IRegisterDependency)
((IRegisterDependency)DependencyResolver).Register(instance);
else
throw new InvalidOperationException("cannot register service");
}
public static T Resolve<T>(string name)
{
return DependencyResolver.Resolve<T>(name);
}
public static T Resolve<T>(string name, params object[] parameters)
{
return DependencyResolver.Resolve<T>(name, parameters);
}
public static T Resolve<T>()
{
return DependencyResolver.Resolve<T>();
}
public static T Resolve<T>(params object[] parameters)
{
return DependencyResolver.Resolve<T>(parameters);
}
public static object Resolve(Type type)
{
return DependencyResolver.Resolve(type);
}
public static IEnumerable<T> ResolveAll<T>()
{
return DependencyResolver.ResolveAll<T>();
}
public static void Clear()
{
DependencyResolver.Clear();
}
}
public class MvcApplication : NinjectHttpApplication
{
private IKernel m_kernel;
// removed stuff
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
IoC.InitilizeWith(new CtsDependencyFactory());
}
protected override IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new FormHandlerModule()
};
m_kernel = new StandardKernel(modules);
return m_kernel;
}
}
由于
答案 0 :(得分:5)
您没有正确使用NInject(或任何DI容器)。你正在做的是使用服务定位器,它似乎正在解决你解决所需依赖关系的问题,但它只是隐藏它。如果你遵循RRR,你将让容器处理解决你的类所需的依赖关系的负担。
Why is using a service locator an anti-pattern?
最后,通过手动解决依赖关系,您可以有效地消除模仿依赖关系的所有机会。这对你来说是否有问题,谁知道呢。这可以通过使用构造函数注入来解决。
关于交换容器的问题。除非你每个问题使用多个容器(这是一个很大的否定),否则你应该只解析项目的根组件并让容器接管。完成所有操作后,您的代码应该不知道存在容器。
我建议您阅读Mark Seemann的Dependency Injection in .NET。