如何使用SimpleInjector

时间:2016-08-08 18:14:51

标签: c# dbcontext simple-injector

我有一个疑问,因为我是依赖和IoC的新手。

我有一个域层(带有业务逻辑)和一个数据层。我们没有实现存储库,我们直接使用EF Core。 它是一个类库项目,我们在AspNetCore web api,WinForms和另一个框架中使用它。

我们的想法是在范围内使用相同的上下文。

问题在于我无法在嵌套方法执行中获得相同的上下文,我确定这是因为我完全不理解这个概念,你能给我一个帮助吗?那个?

示例:

public class MyTest
{
    public void TestContainer()
    {
        var parentContext = MyContainer.Container.GetInstance<MyContext>();
        TestParentAndChildContext(parentContext); 
    }

    private void TestParentAndChildContext(MyContext parentContext)
    {
        var childContext = MyContainer.Container.GetInstance<MyContext>();
        Assert.AreEqual(parentContext, childContext);
    }
}

public class MyContainer
{
    public static Container Container
    {
        get { return container ?? (container = RegisterAndVerifyContainer()); }
    }

    private static Container RegisterAndVerifyContainer()
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new ExecutionContextScopeLifestyle();
        container.Register<DbContext, MyContext>(Lifestyle.Scoped);

        container.Verify();

        return container;
    }
}

1 个答案:

答案 0 :(得分:0)

在Simple Injector中,您通过其抽象注册实现。在您的情况下,您根据MyContext基本类型注册了DbContext。从这一点开始,Simple Injector将知道如果有人要求MyContext,则需要构建DbContext。这是

的全部目的
  

编程到接口,而不是实现

但是,在您的情况下,尽管您通过其抽象注册MyContext,但您直接请求MyContext的新实例,而不是通过其抽象请求它。这会导致Simple Injector在其注册抽象列表中查找MyContext。由于MyContext没有注册(虽然有DbContext,但是这与Simple Injector有关的类型完全不同),Simple Injector会尝试添加缺少的注册。这是成功的,因为MyContext是具体的并且具有单个可解析的构造函数。默认情况下,Simple Injector会将未注册的具体类型解析为Transient

因此MyContext在直接请求时被解析为瞬态。您可以通过将测试更改为以下内容来解决此问题:

public void TestContainer()
{
    using (MyContainer.Container.BeginExecutionContextScope()) {
        var parentContext = MyContainer.Container.GetInstance<DbContext>();
        TestParentAndChildContext(parentContext); 
    }
}

private void TestParentAndChildContext(MyContext parentContext)
{
    var childContext = MyContainer.Container.GetInstance<DbContext>();
    Assert.AreEqual(parentContext, childContext);
}

请注意,Simple Injector通常会检测到这些错误。如果您通过其MyContext基类型注册DbContext,但直接在类型的构造函数中注入MyContext,则在调用{{1}时,Simple Injector将抛出Short Circuited Dependency错误}}

您没有收到警告的原因是因为您在解决操作之前调用了Verify()(您通常不应该在应用程序中调用Verify();而是应该构建所有前面的对象图)。但是,当您在解析GetInstance后再次致电Verify时,您会看到异常突然出现:

MyContext