0

我有ReadModelRepository一个依赖于(但不拥有)一次性类实例的非一次性类ReadModelDbContext。在 aModule中,我想配置我的 Autofac 3.0.2 容器,以便ReadModelDbContext仅在ReadModelRepository创建对象时解决(每个依赖项一个实例)。

这是我目前拥有的:

builder.RegisterType<ReadModelRepository>().As<IReadModelRepository>();
builder.Register(c => new ReadModelDbContext(_connectionStringName)).AsSelf();

但是,我不希望任何任意类都能够ReadModelDbContext使用模块提供的注册来解析。实际上,其他类可能需要解析不同的ReadModelDbContext实例。

为了解决这个问题,我可以使用WithParameter,如以下代码段所示:

builder
    .RegisterType<ReadModelRepository> ().As<IReadModelRepository> ()
    .WithParameter (
        (p, c) => p.ParameterType == typeof (ReadModelDbContext), 
        (p, c) => new ReadModelDbContext (_connectionStringName));

但是,我还需要 Autofac 在解析(或实际上是其解析组件ReadModelDbContext的)生命周期范围结束时自动处理。ReadModelRepository使用WithParameter,这似乎不起作用。

因此,从本质上讲,我只想在外部组件的上下文中注册一个依赖项,并在Dispose最外部组件的生命周期范围结束时调用。这可能吗?

4

3 回答 3

1

也许,这会对你有所帮助。

public class RepositoryManager : IDisposable
{
    private ILifetimeScope m_RootLifetimeScope;
    private ILifetimeScope m_RepositoryScope;
    private bool m_Disposed;

    public RepositoryManager(ILifetimeScope rootLifetimeScope)
    {
        m_RootLifetimeScope = rootLifetimeScope;
    }

    public IReadModelRepository CreateReadModelRepository()
    {
        m_RepositoryScope = m_RootLifetimeScope.BeginLifetimeScope(
                builder =>
                    {
                        builder.RegisterType<ReadModelRepository>().As<IReadModelRepository>();
                        builder.Register(c => new ReadModelDbContext(_connectionStringName)).AsSelf();
                    });
        return m_RepositoryScope.Resolve<IReadModelRepository>();
    }

    public void Dispose()
    {
        if (m_Disposed) return;

        m_RepositoryScope.Dispose(); //ReadModelDbContext will be disposed

        m_Disposed = true;
    }
}

//registration
builder.RegisterType<RepositoryManager>().InstancePerDependency();

//using
using (var repositoryManager = yourContainer.Resolve<RepositoryManager>())
{
    IReadModelRepository repository = repositoryManager.CreateReadModelRepository();
}
于 2013-07-05T03:22:42.707 回答
0

我建议ReadModelRepository依赖Func<Owned<ReadModelDBContext>>.

就像是:

using Autofac.Features.OwnedInstances;

class ReadModelRepository : IReadModelRepository
{
    public ReadModelRepository(Func<Owned<ReadModelDBContext>> contextFactory)
    {
        _ctxFactory = contextFactory;
    }

    public DoSomethingUseful()
    {
        using (var context = _ctxFactory())
        {
            // use context.Value in here;
            // it will be disposed when exiting the block
            ...
        }
    }

    private readonly Func<Owned<ReadModelDBContext>> _ctxFactory;
}

然后,您可以根据需要注册 ReadModelRepository 和 ReadModelDBContext。

这种方法不能解决阻止其他类解析 a 的问题ReadModelDBContext,但您也许可以通过将所有这些类型设置为程序集内部来玩可见性游戏,除了IReadModelRepository. 如果你不能得到类型,你当然不能从容器中请求一个实例。

Autofac Wiki 有一些关于这种方法的文档。

于 2013-07-25T21:03:45.847 回答
0

一段时间后,我实际上采用了一种不同的方法:我ReadModelDbContext使用私钥注册内部组件 ( ):

var privateKey = new object();
builder.Register(c => new ReadModelDbContext(_connectionStringName)).Keyed<ReadModelDbContext>(privateKey);
builder.Register(ctx => new ReadModelRepository(ctx.ResolveKeyed<ReadModelDbContext>(privateKey))).As<IReadModelRepository>();

由于没有其他人拥有密钥,这实际上使ReadModelDbContext注册对ReadModelRepository.

于 2014-05-22T06:52:30.303 回答