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

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

Func<Owned> 

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

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

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

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

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

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

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

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

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

我同意@steinar ,我会认为Autofac是另一个支持你项目的第三方dll。 您的系统依赖于它,为什么要限制自己参考它? 如果ILifetimeScopeIComponentContext洒在你的代码周围,我会更加安心。

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

 public interface IOwned : IDisposable { T Value { get; } } public class OwnedWrapper : Disposable, IOwned { private readonly Owned _ownedValue; public OwnedWrapper(Owned 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(); var c = cb.Build(); 

您现在可以照常解决:

 using (var myOwned = c.Resolve>()) { var service = myOwned.Value; } 

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

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

它将成为内置的.NET类型: ExportLifeTimeContext 。 尽管有这个名字,但这个类并没有真正绑定到.NET ExportFactory 。 构造函数只接受一个值,并在处理该值的生命周期时调用Action

目前,它仅在Silverlight中可用。 对于常规.NET框架,您必须等到.NET 4.x(或者4.0之后的下一个版本)。

我不认为引用Autofac程序集是真正的问题 – 我认为像应用程序代码中出现的Owned的’代码味道’。 应用程序代码不应该关心正在使用什么DI框架,并且在代码中Owned现在会对Autofac产生硬依赖。 所有与DI相关的代码应该干净地包含在一组配置类中(Autofac世界中的模块)。