プロジェクト間で参照が必要ない場合は、ファクトリ/抽象ファクトリを調べることができます。
あなたのUIはビジネスレイヤを知っているので、データレイヤの使用方法を知っているビジネスレイヤのファクトリを定義する必要があります。次に、コンポジションルート(この例ではUIプロジェクト)ですべてのDIを処理します。
、あなたの質問
データ層
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
ビジネス層
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
public class BusinessLogic
{
IDataAccessFactory dataAccessFactory;
public BusinessLogic(IDataAccessFactory dataAccessFactory)
{
this.dataAccessFactory = dataAccessFactory;
}
public void DoSomethingWithData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
に記載された参考文献にこだわり、UIとしてコンソールアプリケーションを使用して、以下の簡単な例
UI
実際の世界の例では、何のためにも抽象化されているように見えるので、それは理にかなった例です。
データレイヤーのデータベース、XMLファイルなどにさまざまなデータアクセスクラスが存在する可能性があります。そのため、ビジネスレイヤーごとにファクトリを定義することができます。抽象的な工場
工場を使用して
は
データ層の核心について、より多くのロジックを含む、または抽象工場としてビジネスロジック層への個々の工場のセットを提供することができます。
ビジネス層
あなたが代わりにコンクリート工場
public class WebPlatformFactory : IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory()
{
return new XmlDataAccessFactory();
}
IPricingFactory GetPricingFactory()
{
return new WebPricingFactory(); // not shown in the example
}
}
と、このような
public interface IPlatformFactory
{
IDataAccessFactory GetDataAccessFactory();
IPricingFactory GetPricingFactory(); // might be in the business project, or another project referenced by it
}
などのビジネス層に抽象工場を持っているかもしれません(追加の具体的な工場を持っているかもしれませんRetailPlatformFactory
など)
の
あなたBusinessLogic
クラスは今
public class BusinessLogic
{
IPlatformFactory platformFactory;
public BusinessLogic(IPlatformFactory platformFactory)
{
this.platformFactory = platformFactory;
}
public void DoSomethingWithData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
Console.WriteLine(dataAccess.GetData());
}
public string GetSomeData()
{
IDataAccessFactory dataAccessFactory = platformFactory.GetDataAccessFactory();
IDataAccess dataAccess = dataAccessFactory.GetDataAccess();
return dataAccess.GetData();
}
}
データ層のようになりますあなたのビジネス層は、もはやあなたは、この例では、データ層に移動することができますので、あなたのUIにIDataAccessFactory
を提供する必要があります
。だから、データ層クラスは
public interface IDataAccess
{
string GetData();
}
public class XmlDataAccess : IDataAccess
{
public string GetData()
{
return "some data";
}
}
public interface IDataAccessFactory
{
IDataAccess GetDataAccess();
}
public class XmlDataAccessFactory : IDataAccessFactory
{
public IDataAccess GetDataAccess()
{
return new XmlDataAccess();
}
}
だろうUI
今、あなたはUIにあなたは、コンテナを設定し、
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IPlatformFactory, WebPlatformFactory>();
var logic = container.Resolve<BusinessLogic>();
logic.DoSomethingWithData();
string useDataInUI = logic.GetSomeData();
Console.WriteLine("UI " + useDataInUI);
Console.ReadKey();
}
と同様の操作UIを実行したいと思いますそして、知っていますデータレイヤー/アクセスについては何もなく、ファクトリの作成をビジネスレイヤーに渡しているだけです。ビジネスレイヤーには、データ(および価格)の参照が格納されています。
いくつかの推奨読書:
Composition Root
Implementing an Abstract Factory
Compose object graphs with confidence
プロジェクト参照(例えば、循環参照)及びDIは、2つの別々の関心事です。参照を追加することは、必ずしも悪いことではありません。適切な答えは、どのツールがDIに使用されているかによって異なります。私はあなたが快適であるDIツールを調査し、ニーズに合わせて機能を評価することをお勧めします。 –
私が上記のことを少し詳しく説明します。多くのDIツールでは、どのようなサービスがどのインタフェースに登録されているのかをどこかに配線しなければなりません。一度登録すると、手動でインスタンスを手動で作成するわけではありません。 DIを適切に使用すると、UIはビジネスオブジェクトのインスタンスを作成せず、UIのコントローラのコンストラクタに注入され、DataAccessはビジネスロジッククラスに注入されます。例えば。 DIツールがどのように動作するのかを理解するのに、特にMVCアプリケーションの場合、特別な生き物として、もう少し時間を費やしています。 –
また、クラスを所属するアセンブリの内部に作成し、インタフェースを公開することだけができます。 AutofacのようなDIコンテナは、すべてのクラスをアセンブリからワイヤリングし、それらのインターフェイスだけで使用できるようにします。 –