仅仅为Owned <T>在我的项目中引用Autofac是不好的设计?

Jay*_*van 10 c# idisposable autofac

我最近成为了Autofac的OwnedInstances功能的重要用户.例如,我用它来提供一个工厂来为我的数据库创建一个工作单元,这意味着我依赖于UnitOfWork工厂的类要求类型的对象:

Func<Owned<IUnitOfWork>>
Run Code Online (Sandbox Code Playgroud)

这非常有用 - 非常适合将IDisposable保留在我的界面之外 - 但它需要付出代价:因为Owned <>是Autofac程序集的一部分,我必须在我知道Owned <>的每个项目中引用Autofac. ,并在每个代码文件中添加"使用Autofac.Features.OwnedInstances".

Func <>具有内置于.NET框架的巨大好处,因此我毫不怀疑将Func用作通用工厂包装器是可以的.但Owned <>在Autofac程序集中,每次我使用它时,我都会创建一个对Autofac的硬引用(即使我在接口方法参数中对Autofac的唯一引用是Owned <>类型).

我的问题是:这是件坏事吗?这会开始以某种方式让我回头,我还没有考虑到这一点吗?有时我会有一个由许多其他项目引用的项目,因此我自然需要将其依赖关系尽可能接近零; 我是通过将Func <OwnedOfWork >>(实际上是一个数据库事务提供程序)传递给这些接口中的方法(否则将是autofac-nonnostic)来做恶的?

也许如果Owned <>是一个内置的.NET类型,这整个困境会消失吗?(我是否应该屏住呼吸?)

Pet*_*old 11

我同意@steinar,我会认为Autofac是另一个支持你项目的第三方dll.您的系统依赖于它,为什么要限制自己参考它?如果ILifetimeScope或者IComponentContext在代码周围散布,我会更加保守.

那就是说,我感受到了你的安慰.毕竟,DI容器应该在幕后工作,而不是"溢出"到代码中.但是我们可以轻松创建一个包装器和一个界面来隐藏它Owned<T>.考虑以下接口和实现:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

注册可以使用注册源或构建器完成,例如:

var cb = new ContainerBuilder();
cb.RegisterGeneric(typeof (OwnedWrapper<>)).As(typeof (IOwned<>)).ExternallyOwned();
cb.RegisterType<SomeService>();
var c = cb.Build();
Run Code Online (Sandbox Code Playgroud)

您现在可以照常解决:

using (var myOwned = c.Resolve<IOwned<SomeService>>())
{
    var service = myOwned.Value;       
}
Run Code Online (Sandbox Code Playgroud)

您可以将此接口放在系统中的公共名称空间中,以便于包含.这些Owned<T>OwnedWrapper<T>现在都隐藏在您的代码中,只有IOwned<T>暴露.如果需求发生变化并且您需要将Autofac替换为另一个DI容器,则此方法的摩擦力会大大降低.


ste*_*nar 10

我想说在"企业应用程序"解决方案(或任何需要灵活性的应用程序)的每个项目中引用一组定义明确的核心第三方DLL都没关系.我认为在每个需要它的项目中依赖至少以下内容没有错:

  • 日志框架(例如log4net)
  • 一些IoC容器(例如Autofac)

事实上,这些不是核心.NET框架的一部分,不应该阻止我们自由地使用它们.

与可能的好处相比,我能看到的唯一可能的负面影响相对较小:

  • 这可能使普通程序员更难理解应用程序
  • 如果您只是使用.NET框架,将来可能会遇到版本兼容性问题
  • 将所有这些引用添加到每个解决方案中都有明显但很小的开销