Inject IKernel 作为 Ninject 中的属性



我在公共库中使用依赖解析器接口作为抽象。这使我能够灵活地切换容器。给定下面的接口和静态 IoC 类,我需要使用没有从全局 asax 传递IKernel的工厂初始化 IoC。

请参阅下面我如何使用NinjectHttpApplication库来创建 Ninject 内核。

这就是问题所在;CtsDependencyFactory中的IKernel属性始终null

宁注射不是这样注射自己吗?我应该使用不同的方法将IKernel传递给工厂吗?我在 Ninject 中找不到像 ObjectFactory in 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;
    }
}

谢谢

您没有正确使用 NInject(或任何 DI 容器(。您正在做的是使用服务定位器,它似乎正在解决所需依赖项的问题,但它只是隐藏了它。如果您遵循 RRR,您将让容器处理解决类所需的依赖项的负担。

为什么使用服务定位器是一种反模式?

最后,通过手动解析依赖项,您可以有效地消除模拟依赖项的所有机会。这对你来说是否是一个问题,谁知道呢。这是通过使用构造函数注入来解决的。

关于交换容器的问题。除非你为每个问题使用多个容器(这是一个很大的不(,否则你应该只解决项目的根组件并让容器接管。一旦一切都说完了,你的代码应该不知道有一个容器存在。

我建议阅读Mark Seemann的Dependency Injection in .NET版本。

最新更新