在Ninject中将IKernel注入属性

she*_*per -1 .net c# dependency-injection ninject

我在公共库中使用依赖解析器接口作为抽象.这使我可以灵活地切换容器.鉴于下面的接口和静态IoC类,我需要使用不带IKernel全局asax 的工厂初始化IoC .

请参阅下面我如何使用NinjectHttpApplicationbase创建Ninject内核.

这是问题所在; 该IKernel物业CtsDependencyFactory始终null.

Ninject不会像这样注射自己吗?我应该使用不同的方法传递IKernel给工厂吗?我找不到像静态类ObjectFactoryStructureMap的Ninject得到一个参考解析器.

任何帮助表示赞赏.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

gcs*_*cso 5

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

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

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

关于交换容器的问题.除非你每个问题使用多个容器(这是一个很大的否定),否则你应该只解析项目的根组件并让容器接管.完成所有操作后,您的代码应该不知道存在容器.

我建议阅读Mark Seemann 在.NET中依赖注入.