4

私は、非常に大きな Delphi アプリ (DB には 249 個のテーブルがあります!) を書き直した C# アプリのモジュール化を任されています。ビジネス上の制約により、.NET の完全な再設計と全体的なアーキテクチャの改善が禁止されているため、基本的には、C# で Delphi アプリのモジュールのモジュールを段階的に書き直しています。完了するまで、スイートは保留中の書き換えと、MEF を使用して統合したい C# アプリ モジュールの混合で構成されます。

このアプリは、勤怠管理とアクセス制御に関係しており、「従業員休暇」や「訪問者」などの多様なビジネス領域を備えています。これらは別のプロジェクトにする必要があると思います。そこでは、書き直された C# プロジェクトを交換でき、MEF コンテナーにインポートされます。各プロジェクトは をIBusinessArea最高レベルの定義としてエクスポートし、次にこれらは のような標準の共有インターフェースをエクスポートIServiceし、 のようなビジネス領域で利用可能なサービスを導入しますCreateEmployeeCommand各サービスは、コンテナーとのサービスのインターフェースを標準化し、サービスのメタデータ、サービスを使用できるユーザーに関するデータなどを含むクラスになります。

私は正しい方向に向かっていますか?もしそうなら、メタデータをクラスとして保存および公開するにはどうすればよいIBusinessAreaですIServiceか?型指定されていないメタデータ属性の軍団に対して?

4

1 に答える 1

4

これまでのところ、あなたの言うことはすべて私には理にかなっているように聞こえます。特定の領域をモジュール化し、さまざまな抽象化レベルでインターフェイスを定義し、各モジュールをさまざまなインターフェイスでエクスポートします。つまり、各モジュールは、実装する複数のインターフェイスとして登録されます。必要な抽象化のレベルに応じてモジュールを解決し、すべてのサービス、すべてのビジネス領域などを取得できます。したがって、私の意見では、正しい方向に向かっていると思います。

メタデータをどう扱うか?MEF は、メタデータのエクスポートを提供します。これは、使用するのに妥当なものと思われます。完全には理解できなかったかもしれませんが、MEF メタデータのエクスポートで非常に悪い経験をしました。私が思い出す限り、MEF はメタデータをキーと値のペアとして保存します。キーは文字列です。

型付きメタデータのエクスポートおよび使用関数を使用しても、メタデータは実際には型安全ではありません。「PropertyA」というプロパティを持つインターフェイス「IMetadata」がありFoo、MEF が typesafe と呼ぶ方法(IMetadata を実装するメタデータ)。というプロパティを持つ 2 番目のメタデータ インターフェイス「IMetadataB」があるとしPropertyAます。Fooここでメタデータを使用した解決を要求するとIMetadataB、最初に登録したインスタンスが取得されます。これは、MEF がPropertyAメタデータのキーと値のペアに存在することに満足し、実装する適切なプロキシ メタデータ タイプを構築するためIMetadataBです。

簡単に言えば、私は MEF に対して不公平かもしれませんが、メタデータ サポートに組み込まれている MEF を使用するのをやめたので、同じことをすることをお勧めします。

私は非常に複雑で長いメタデータを扱っているため、エクスポートするクラスに密接に結合したいクラスのドキュメントを含め、少し型破りではありますが、私にとって非常にうまく機能するシステムを開発しました。

基本的に、メタデータのインターフェイスとベースクラスを定義します。たとえばMetadataBase、 という文字列プロパティを使用しますDescription

public class MetadataBase : IMetadata
{
    public string Description { get; set; }
}

その後、メタデータが必要なすべてのクラスについて、FooMetadataこの基本クラスからクラス ( ) を派生させ、XAML で部分的に定義します。次に、XAML で、プロパティのクラス固有の値を定義します。次に例を示します。

<md:MetadataBase.Description>
    The description of my class goes here
</md:MetadataBase.Description>

カスタム属性を使用して、メタデータ型を実際のクラスに関連付けます。

[Export(typeof(IFoo))]
[AssociatedMetadata(typeof(FooMetadata))]
public class Foo : IFoo
{
    // Whatever
}

オブジェクトの拡張メソッドを使用すると、リフレクションを介してメタデータを読み取ることができます。

public static IMetadata GetMetadata(this object objectWithMetadata)
{
     // Read attribute type
     // Create instance of the metadata type, i.e. FooMetadata
     // A caching mechanism can be implemented, if needed, but, honestly,
     // my really big metadata objects including images and stuff like this
     // are created within 3-5 ms
     // Return this instance
}

これで、基本的にそこにいます。次のようなメタデータを持つオブジェクトのメタデータを読み取ることができます。

var myObjectsMetadata = myObject.GetMetadata();

AssociatedMetadataAttributeインターフェイスを実装し、このインターフェイスのメタデータに型を登録するときに、このメタデータを MEF で利用できます。1 つのプロパティを保持し、他には何も保持しない 1 つのタイプのメタデータ (タイプ) があるため、混乱することはありません。

この解決策はすべてに適した方法ではありませんが、私はそれを気に入っており、あなたの質問はそれを提示する良い機会です. それが役に立てば幸い!

于 2013-10-02T13:16:05.290 に答える