如何使用DI与Castle正确实例EF对象数据上下文?

时间:2012-02-27 20:09:16

标签: c# model-view-controller dependency-injection inversion-of-control castle-windsor

到目前为止,我所拥有的是以下安装程序:

/// <summary>
/// Registers all repositories.
/// </summary>
public class RepositoryInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            AllTypes.FromAssemblyContaining<EntityFrameworkLinkRepository>()
                .BasedOn<IRepository>()
                .WithService.Select(ByConvention)
                .Configure(WithDependencies)
                .LifestylePerWebRequest()
            );
    }

    private IEnumerable<Type> ByConvention(Type type, Type[] types)
    {
        if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
        {
            return Enumerable.Empty<Type>();
        }
        return new[] { type.BaseType };
    }

    private void WithDependencies(ComponentRegistration component)
    {
        Type type = component.Implementation;
        string key;
        if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
        {
            key = type.Name;
        }
        else
        {
            key = type.Name.Substring(0, type.Name.Length - type.BaseType.Name.Length);
        }
        component.DependsOn(new
        {
            connectionString = ConnectionString(key)
        });
    }

    private string ConnectionString(string key)
    {
        string connectionString = Config.GetConnectionString(key);
        return connectionString;
    }
}

它解析了存储库。

现在,存储库的实例如下:

public class EntityFrameworkLinkRepository : LinkRepository
{
    private readonly ObjectDataContext context; // TODO shouldn't this be receiving a lifetimed ODC, instead of just the connString?

    public EntityFrameworkLinkRepository(string connectionString)
    {
        if (connectionString == null)
        {
            throw new ArgumentNullException("connectionString");
        }
        this.context = new ObjectDataContext(connectionString);
    }

// etc...

我的问题是我应该如何解析对象数据上下文,而不仅仅是创建一个新的(甚至不处理它),使用DI通过Castle解析EF数据上下文的正确方法是什么?

我想我希望ODC能够在所有与同一个Web请求相关的存储库中共享(这对我来说是最有意义的,对吗?)

但是由于我ObjectContext的实现是针对EntityFramework的,我对于如何解决它有点迷茫,我应该用这样的东西明确注册吗? / p>

container.Register(
    Component
    .For<ObjectDataContext>()
    .DependsOn(new
    {
        connectionString = ConnectionString("EntityFramework")
    })
    .ImplementedBy<ObjectDataContext>()
);

2 个答案:

答案 0 :(得分:4)

这样的事情应该有效:

container.Register(
    .Component.For<ObjectDataContext>()
    .DependsOn(
        Dependency.OnValue(
            "connectionString", ConnectionString("EntityFramework")))
    .LifeStyle.PerWebRequest);

答案 1 :(得分:2)

您应该为ObjectDataContext获取构造函数参数。如果你正在使用MVC,你还应该实现一个WindsorControllerFactory,所以你所有的控制器都是由Windsor创建的,并且为你创建了任何构造函数依赖项。您不应该创建任何“服务”的实例和实例

如何注册ObjectDataContext实际上取决于您编写的内容/类依赖于它。因此,如果您已将代码写入ObjectDataContext本身,那么您提供的示例就可以了。但是如果你写了一个接口,那么就需要这样的东西......

container.Register(
    Component
        .For<IObjectDataContext>()
        .ImplementedBy<ObjectDataContext>()
        .DependsOn(new { connectionString = ConnectionString("EntityFramework") })
        .LifeStyle.PerWebRequest
);
相关问题