Я согласен с @ 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();
}
}
Регистрация может быть осуществлена либо с использованием источника регистрации, либо с помощью компоновщика, например, как это:
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;
}
Вы можете разместить этот интерфейс в общем пространстве имен в вашей системе для легкого включения.
И Owned<T>
, и OwnedWrapper<T>
теперь скрыты от вашего кода, отображается только IOwned<T>
. Если требования изменятся, и вам нужно заменить Autofac другим DI-контейнером, при таком подходе будет гораздо меньше трений.