これも私によく戸惑っています。それについて幸せではありませんが、私は常にIDisposableオブジェクトを一時的に返すことは決して最善ではないという結論に達しました。
最近、私は自分自身のために質問を言い換えました:これは本当にIoCの問題か.netフレームワークの問題ですか?とにかく、処分は厄介です。意味のある機能的な目的はなく、技術的なものだけです。 IoCの問題よりも、私たちが対処しなければならないフレームワークの問題です。
私がDIについて気に入っているのは、技術的な詳細を気にすることなく、私に機能を提供する契約を求めることができるということです。私は所有者ではない。それがどの層に入っているかについての知識はなく、契約を履行するためにどの技術が必要かについての知識はなく、生涯心配はありません。私のコードはきれいに見え、非常にテスト可能です。私は彼らが所属する層に責任を実装することができます。
このルールに例外があり、生涯を整理する必要がある場合は、その例外を作りましょう。私が好きかどうか。インターフェイスを実装しているオブジェクトが私にそれを処分する必要がある場合は、そのオブジェクトをできるだけ短いものとして使用するようトリガーされて以来、私はそれについて知りたいと思っています。あとで処理される子コンテナを使用して解決することによって、トリックは、私が必要以上にオブジェクトを長く生かし続ける原因になる可能性があります。オブジェクトの登録時に、オブジェクトの許容寿命が決定されます。子コンテナを作成し、それを一定期間保持する機能ではありません。
私たちは開発者が処分を心配する必要がある限り、これまでどんな一時的な使い捨てオブジェクトもできるだけ少量注入しようとします。 1.私はオブジェクトをIDisposableではないようにしようとします。たとえば、ディスポーザブルオブジェクトをクラスレベルではなく、より小さなスコープに保つことによって。 2.オブジェクトを再利用可能にして、別の生涯マネージャを適用できるようにしようとしています。
これが実現できない場合は、工場を使用して、注入された契約のユーザーが所有者であり、その責任を負うべきであることを示します。
1つの注意点があります。契約者を非処分から使い捨てに変更することは大きな変更になります。その時、インターフェースはもはや登録されなくなり、工場へのインターフェースになります。しかし、私はこれが他のシナリオにも当てはまると思います。子供のコンテナを使用することを忘れると、その瞬間から記憶上の問題が生じます。工場アプローチはIoC解決例外を引き起こすでしょう。
いくつかのサンプルコード:
using System;
using Microsoft.Practices.Unity;
namespace Test
{
// Unity configuration
public class ConfigurationExtension : UnityContainerExtension
{
protected override void Initialize()
{
// Container.RegisterType<IDataService, DataService>(); Use factory instead
Container.RegisterType<IInjectionFactory<IDataService>, InjectionFactory<IDataService, DataService>>();
}
}
#region General utility layer
public interface IInjectionFactory<out T>
where T : class
{
T Create();
}
public class InjectionFactory<T2, T1> : IInjectionFactory<T2>
where T1 : T2
where T2 : class
{
private readonly IUnityContainer _iocContainer;
public InjectionFactory(IUnityContainer iocContainer)
{
_iocContainer = iocContainer;
}
public T2 Create()
{
return _iocContainer.Resolve<T1>();
}
}
#endregion
#region data layer
public class DataService : IDataService, IDisposable
{
public object LoadData()
{
return "Test data";
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
/* Dispose stuff */
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
#endregion
#region domain layer
public interface IDataService
{
object LoadData();
}
public class DomainService
{
private readonly IInjectionFactory<IDataService> _dataServiceFactory;
public DomainService(IInjectionFactory<IDataService> dataServiceFactory)
{
_dataServiceFactory = dataServiceFactory;
}
public object GetData()
{
var dataService = _dataServiceFactory.Create();
try
{
return dataService.LoadData();
}
finally
{
var disposableDataService = dataService as IDisposable;
if (disposableDataService != null)
{
disposableDataService.Dispose();
}
}
}
}
#endregion
}
私のソリューションは、適切かつ十分に成文化寿命管理でIOCを使用することです。(彼らは少し異なる動作が)AutoFacと城ウィンザーは、持っています。デフォルトのライフタイムマネージャの下で過渡現象を扱うとき、ユニット2.1は単に失敗します。 – user2864740