我最近成为 Autofac 的 OwnedInstances 功能的重度用户。例如,我用它来提供一个工厂来为我的数据库创建一个工作单元,这意味着我依赖于 UnitOfWork 工厂的类正在请求以下类型的对象:
Func<Owned<IUnitOfWork>>
这非常有用——非常适合 keeping IDisposable out of my interfaces --但它是有代价的:因为 Owned<> 是 Autofac 程序集的一部分,我必须在我的每个知道 Owned<> 的项目中引用 Autofac,并在每个代码中加入“using Autofac.Features.OwnedInstances”文件。
Func<> 具有构建到 .NET 框架中的巨大好处,因此我毫不怀疑将 Func 用作通用工厂包装器是很好的。但是 Owned<> 在 Autofac 程序集中,每次我使用它时,我都会创建对 Autofac 的硬引用(即使我对 Autofac 的唯一引用是接口(interface)方法参数中的 Owned<> 类型)。
我的问题是:这是一件坏事吗?这会以某种我尚未考虑的方式开始反咬我吗?有时我会有一个项目被许多其他项目引用,因此我自然需要使其依赖性尽可能接近于零;我是否通过将 Func
也许如果 Owned<> 是一个内置的 .NET 类型,这整个困境就会消失? (我是否应该为此屏住呼吸?)
最佳答案
我同意 @steinar ,我认为 Autofac 是另一个支持您的项目的第 3 方 dll。你的系统依赖它,你为什么要限制自己引用它?如果 ILifetimeScope
我会更关心或 IComponentContext
散布在您的代码周围。
也就是说,我感受到了你的关心。毕竟,DI 容器应该在幕后工作,而不是“溢出”到代码中。但是我们可以轻松地创建一个包装器和一个接口(interface)来隐藏 Owned<T>
。 .考虑以下接口(interface)和实现:
public interface IOwned<out T> : IDisposable
{
T Value { get; }
}
public class OwnedWrapper<T> : Disposable, IOwned<T>
{
private readonly Owned<T> _ownedValue;
public OwnedWrapper(Owned<T> ownedValue)
{
_ownedValue = ownedValue;
}
public T Value { get { return _ownedValue.Value; } }
protected override void Dispose(bool disposing)
{
if (disposing)
_ownedValue.Dispose();
}
}
可以使用注册源或构建器来完成注册,例如像这样:
var cb = new ContainerBuilder();
cb.RegisterGeneric(typeof (OwnedWrapper<>)).As(typeof (IOwned<>)).ExternallyOwned();
cb.RegisterType<SomeService>();
var c = cb.Build();
您现在可以像往常一样解决:
using (var myOwned = c.Resolve<IOwned<SomeService>>())
{
var service = myOwned.Value;
}
您可以将此接口(interface)放在系统中的公共(public)命名空间中以便于包含。
Owned<T>
和 OwnedWrapper<T>
现在隐藏在您的代码中,只有 IOwned<T>
暴露了。如果需求发生变化并且您需要将 Autofac 替换为另一个 DI 容器,则使用这种方法会减少很多摩擦。
关于c# - 在我的项目中仅针对 Owned<T> 引用 Autofac 是不是糟糕的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5438274/