简单注入器:所选控制器的不同DbContext

时间:2014-03-11 10:50:26

标签: c# asp.net-mvc entity-framework dependency-injection simple-injector

我试图在我的MVC应用程序中分离读/写。我使用Simple Injector作为Ioc,我有以下结构:

new Service(
  new Repository(
     new UnitOfWork(
        new DbContext())))

因此UnitOfWork已按照网络请求注册所有其他Transient

因此,如果控制器是只读的,那么想法是创建单独的只读控制器并注册DbContext以提供不同的连接。这可以通过improved RegisterWithContext extension实现,但在我的情况下它不起作用,因为并非所有图形节点都是Transient

有没有办法(比使用改进的RegisterWithContext扩展注册每个存储库更优雅,其中需要提供另一个只读UnitOfWork并手动解析传递到{{1}的所有其他参数如何实现所描述的场景?

1 个答案:

答案 0 :(得分:3)

由于选择基于控制器的类型,因此您可以使用自定义IControllerFactory进行决策。例如:

public class ConnectionSelector {
    public bool AsReadOnly { get; set; }
}

private class ReadOnlySwitchControllerFactory : DefaultControllerFactory {
    private readonly Container container;

    public ReadOnlySwitchControllerFactory(Container container) {
        this.container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext, 
        Type controllerType) {
        var selector = this.container.GetInstance<ConnectionSelector>();

        selector.AsReadOnly = 
            typeof(IReadOnlyController).IsAssignableFrom(controllerType);

        return base.GetControllerInstance(requestContext, controllerType);
    }
}

您可以按如下方式注册:

container.RegisterPerWebRequest<ConnectionSelector>();

container.RegisterPerWebRequest<DbContext>(() => new DbContext(
    container.GetInstance<ConnectionSelector>().AsReadOnly 
        ? "ReadOnlyConnection" 
        : "NormalConnection"));

container.RegisterSingle<IControllerFactory>(
    new ReadOnlySwitchControllerFactory(container));