使用多个程序集和不同的实体连接进行Autofac注册

时间:2011-04-12 08:00:39

标签: entity-framework ioc-container autofac

我们有两个程序集,包含自己的Entity-Framework EDMX& repositoriy对象。这些是在ASP.NET Web应用程序中使用Autofac注册的。

这些程序集与架构非常相似(但EDMX不同)我们发现最后注册的EntityConnection是两个程序集中使用的EntityConnection。我们需要将EntityConnection的使用限制为仅由程序集或命名空间的类型使用。

var assembly = typeof(Activity).Assembly;
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
builder.Register(reg => new EntityConnection(ConnectionString));

var assembly = typeof(User).Assembly;
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
builder.Register(reg => new EntityConnection(ConnectionString));

有没有办法注册EntityConnection并限制EntityConnection的深度?将每个EntityConnection限制为它所属的程序集?

这是一个伪代码示例,说明我们如何注册EntityConnection以仅在程序集或命名空间中使用。

builder.Register(reg => new EntityConnection(ConnectionString)).ForNamespace("x");

3 个答案:

答案 0 :(得分:2)

尝试在更高的抽象层次上解决问题。由于您有两个单独的域(一个包含Activity实体,另一个包含User实体),因此在应用程序设计中明确地使用它会很方便。例如,为每个域定义某种工厂:

public interface IActivityDomainContextFactory
{
    ObjectContext CreateNew();
}

public interface IPeopleDomainContextFactory
{
    ObjectContext CreateNew();
}

您现在可以轻松地为每个接口创建一个实现,在Autofac ContainerBuilder中注册它们,让您的服务依赖于其中一个接口,而不是依赖于EntityConnection

在这种情况下,您当然仍然依赖于实体框架本身(请参阅here了解如何将其抽象出来),但这会使您的配置更容易,更不易碎,性能更好,以及您的应用程序代码更易于维护。

我希望这会有所帮助。

答案 1 :(得分:2)

您可能想要注册/注明您的注册。见TypedNamedAndKeyedServices - Autofac

我认为这解决了你的一半问题,如何注册类型。另一半是在决议中。由于你通过汇编扫描进行自动注册,这可能需要更多的诡计。

答案 2 :(得分:1)

有很多好的建议可以改善这一点,所以只需将我的解决方案记录为如何在Autofac中执行此操作。

诀窍是为连接使用命名服务,然后为每个程序集中的类型自定义参数解析,以便EntityConnection参数获得命名实例:

builder.Register(reg => new EntityConnection(ConnectionString))
    .Named<EntityConnection>("activities");
builder.RegisterAssemblyTypes(typeof(Activity).Assembly)
    .AsImplementedInterfaces()
    .WithParameter(
        (pi, c) => pi.ParameterType == typeof(EntityConnection),
        (pi, c) => c.ResolveNamed<EntityConnection>("activities"));

builder.Register(reg => new EntityConnection(ConnectionString))
    .Named<EntityConnection>("users");
builder.RegisterAssemblyTypes(typeof(User).Assembly)
    .AsImplementedInterfaces()
    .WithParameter(
        (pi, c) => pi.ParameterType == typeof(EntityConnection),
        (pi, c) => c.ResolveNamed<EntityConnection>("users"));