4

我刚刚开始学习依赖注入,我被困在这里。

我的项目在实体框架 DbContext 上有一个 WCF 数据服务。

public class MyDataService : DataService<MyDbContext>
{

    protected override MyDbContext CreateDataSource()
    {
        // I want to use dependency injection for this
        return new MyDbContext();
    }
}

该类是
a) IIS 托管,所以我没有任何控制 b) 用于集成测试,使用创建var host = new DataServiceHost(type, new Uri[] { });

两者都为 MyDbContext 使用不同的构造函数

所以基本上是用这个注入上下文

    protected override MyDbContext CreateDataSource()
    {
        INinjectModule module = ???; // - 
        IKernel kernel = new StandardKernel(module);
        return kernel.Get<MyDbContext>();
    }

所以问题是,在这种情况下,最佳实践是什么?我是不是该:

a) 在主项目和服务使用的类库中创建一个模块 b) 在包含 Ninject 模块的 DataService 项目中创建一个公共静态变量。c) 在包含 Ninject 内核的 D​​ataService 项目中创建一个公共静态变量 d) 其他东西。

我更喜欢类似的东西

    protected override MyDbContext CreateDataSource()
    {
        DefaultKernel.Get<MyDbContext>();
    }
4

1 回答 1

3

首先,你应该有一个Composition Root。也就是说,您Kernel创建的单个位置(不是在每个函数中)。

其次,你不需要在NinjectModule这里......你要求 Ninject 创建一个具体对象的实例(在几乎所有情况下......都违背了目的)。

您应该创建的是将其单独NinjectModule传递给Kernel.. 的构造函数,如下所示:

interface IContext {
}

class MyDbContext : DbContext, IContext {
}

class YourModule : NinjectModule {
    protected override void Bind() {
        Bind<IContext>().To<MyDbContext>();
    }
}

// In your composition root somewhere
var kernel = new StandardKernel(new NinjectModule[] { new YourModule() });

// in your createdatasource method
kernel.Get<IContext>();

这会让你开始。通常,您的组合根是驱动在整个应用程序中注入对象的原因,从而消除了传递的需要Kernel(在当前设置中您必须这样做)。

开始使用 DI/IoC 时很难理解的是,创建整个依赖关系图是容器的工作。因此,如果您设置以下绑定:

IContract1 -> ConcreteObject1
IContract2 -> ConcreteObject2
IContract3 -> ConcreteObject3

..并具有以下设置:

class ConcreteObject1 : IContract1 {
    public ConcreteObject1(IContract2 contract3) {
    }
}

class ConcreteObject2 : IContract2 {
    public ConcreteObject2(IContract3 contract3) {
    }
}

如果您向容器询问IContract1(将是ConcreteObject1)的具体实现,那么它将创建它....但是:ConcreteObject1需要IContract2在构造函数中具体实现。所以容器说“等等,我知道如何创建这个”.. 并传入一个ConcreteObject2. 再一次,它说“等等,想要一个..ConcreteObject2的具体实现,它又去取一个。IContract3

希望这会有所帮助。

于 2013-07-03T10:35:31.360 回答