0

この質問は、私が以前に尋ねた質問と非常に密接に関連していますが、それらが同じものだとは思わないので、それらを分割するのが賢明だと思いました (質問を聞いたとき、これは少し皮肉なことです)。

前の質問

2 つのプロジェクトに分割された Web アプリケーションがあります。

1) ASP.NET サイト 2) ビジネス オブジェクト、ロジック レイヤー メソッド、および DAL メソッドを含む DLL。それらは異なる名前空間に分割されていますが、すべて同じ DLL 内にあります。

それを見て開発を拡張すればするほど、私は間違った道を進んでいることに気づきました。職務を明確に分離できるように、それらを個別の DLL に分割したかったのです。

さまざまな DLL のコードを取得すると、多くのクラスが互いに呼び出していることに気付きました。たとえば、クライアント オブジェクトのリストが DAL で作成されると、companyDAL.cs も呼び出され、クライアントが属する会社のリストが取得されます。これで、互いに直接参照する 2 つのクラスができました。これはかなり悪いことのようです!臭いがしましたが、続けて、できる限り物を分離しようとしました.

そのために、すべてのオブジェクトをインターフェイスに取り出し、それらへのすべての参照をインターフェイスに変更しました。

私はある種の DI を使用することを望んでいました (現時点ではそれについて学んでいます)。そのため、オブジェクトごとに、その DLL のファクトリーを取り込むコンストラクターを作成しました (このファクトリーは、クラスが可能にする各オブジェクトの新しいインスタンスを作成します)。必要とする)。また、常に 1 つのファクトリが使用されるように、デフォルト ファクトリを使用して DI コンストラクタを呼び出すデフォルト コンストラクタも追加しました。

それはすべてコンパイルされたので、スピンしてスタックオーバーフローを取得しました! これは、お互いを必要とする 2 つのクラスがある場合、もう一方なしではインスタンス化できないことを完全に認識していました。

Factory
{
   IClient CreateNewIClient()
   {
         return new Client();
   }

   ICompany CreateNeIwCompany()
   {
          return new Company();
   }
}

Client
{
    private ICompany _company;

    public Client() : this (new Factory()) {}

    public Client(Factory factory)
    {
        _company = factory.CreateNewICompany();
    }

    public Client GetClientbyID(int id)
    {
       .... do stuff to get client from db
       ... got client object and companyid from db.
         client.Company = _company.GetCompanybyID(companyid);
        return client;
    }
}

 Company
 {
    private IClient _client;

    public Company() : this (new Factory()) {}

    public Company(Factory factory)
    {
        _client = factory.CreateNewIClient();
     }

    public Company GetCompanyWithAllClients(int companyid)
    {
         .... do stuff to get a company out and client ids
         .... for each client id found
          company.Clients.add(_client.GetClientByID(clientid));
          return company;
    } 
 } 
  • 私はDIのことについてすべて間違っているのでしょうか、その工場のアイデアは大丈夫​​ですか?

  • お互いに必要なクラスを避けるにはどうすればよいですか? 現時点でそのようになっているのは、コードの繰り返しを避けるためです。よりクリーンな SQL を記述して、すべてを一度に、または少なくとも同じメソッドのいくつかのクエリで取得できると確信していますが、別の場所でコードを繰り返すことは避けようとしていました。

あらゆる提案に感謝します。

4

2 に答える 2

1

これは、問題の明確化ほどの答えではありません。あなたの工場は物事をやや複雑にしていると思います(まったくコンパイルできないのに対して、スタックオーバーフロー例外が発生するという点で)。

問題は循環依存です。B のインスタンスなしで A をインスタンス化することはできず、A のインスタンスなしで B のインスタンスをインスタンス化することはできません。

public class Company : ICompany
{
    private IClient _client;

    // OK so first build a client and pass it in
    public Company(IClient client)
    {
       _client = _client;
    }
}

public class Client : IClient
{
    private ICompany _company;

    // OK so first build a company and pass it in.  Oh.  I can't... :(
    public Client(ICompany company)
    {
        _company = company;
    }    
}

Misko には、これに関する記事があり、役に立つかもしれません

基本的に:クラスの設計に問題があり、修正する必要があります。工場は問題を混乱させているだけです:)

于 2009-04-18T17:10:04.533 に答える
0

NHibernate や Linq to SQL などの DAL 用の ORM ツールを使用できますか? NHibernate は、(必要に応じて) 双方向リンクを使用してデータをオブジェクトにマップします。

編集:タイプミス

乾杯、ロク

于 2009-04-18T16:17:08.917 に答える