MEFコンストラクタ・インジェクション
-
18-09-2019 - |
質問
私はMEFのコンストラクタ・インジェクションの属性を把握しようとしています。私は、コンストラクタのパラメータをロードするためにそれを伝える方法は考えている。
これは、私がロードしようとしているプロパティです。
[ImportMany(typeof(BUsers))]
public IEnumerable<BUsers> LoadBUsers { get; set; }
ここで私はアセンブリをインポートするために使用しているコードです。
try
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog("DI"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
ここで私がロードしようとしているクラスです。
[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
[ImportingConstructor]
public EditProfile(string Method, string Version)
{
Version = "2";
Action = "Edit";
TypeName = "EditProfile";
}
解決
、コンストラクタのパラメータは、輸入品になります。デフォルトでは、何を(契約名)をインポートしていることはあなたがにインポートされたパラメータやプロパティの型に基づいています。したがって、この場合には、両方のあなたの輸入契約タイプは、文字列であり、第1及び第2のパラメータの間には実質的な違いはありません。
あなたはそれがために設計されたものを必ずしもではない設定値を供給するために輸入を使用しようとしているように、に見えます。
:それはあなたがやりたいことを得るために、あなたはこのように、各パラメータの契約名をオーバーライドする必要があります[ImportingConstructor]
public EditProfile([Import("Method")] string Method, [Import("Version")] string Version)
{ }
次に、あなたのコンテナのメソッドやバージョンのための輸出を必要としています。これを行う1つの方法は、単にそれらを直接追加することです。
var container = new CompositionContainer(catalog);
container.ComposeExportedValue("Method", "MethodValue");
container.ComposeExportedValue("Version", "2.0");
container.ComposeParts(this);
(ComposeExportedValueが実際に静的AttributedModelServicesクラスに定義された拡張メソッドであることに注意してください。)
あなたには、いくつかの並べ替えの設定ファイルから、これらの値を読みたい場合は、、設定を読み込み、コンテナへの輸出としてそれに値を提供し、独自の輸出プロバイダを作成することができます。
これを処理する別の方法は、名前だけで設定値へのアクセスを提供するインターフェースをインポートして、コンストラクタの本体から必要な値を取得することです。
他のヒント
私はダニエルのソリューションが好きです。しかし、私が見る唯一の事はして[ImportingConstructor]カスタマイズされたCTOR用と輸出用部品(CompopositionContrainerを()が作成されます)俳優の間でパラメータ名の緊密な結合があります。たとえば、「メソッド」は、2つの両方の場所に一致することがあります。それは俳優とエクスポートの部分は違いプロジェクトである場合、書き出し部分を維持することが困難になります。
それが可能であるならば、私は輸出の部分クラスに二CTORを追加します。たとえばます:
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
[ImportingConstructor]
public EditProfile(EditProfileParameters ctorPars)
: this(ctorPars.Method, ctorPars.Version) {}
public EditProfile(string Method, string Version)
{
Version = "2";
Action = "Edit";
TypeName = "EditProfile";
}
EditProfileParametersのクラスは簡単です:方法およびバージョンの二つの性質ます:
[Export]
public class EditProfileParameters{
public string Method { get; set; }
public string Version { get; set; }
}
重要な点は、クラスへのエクスポート属性を追加することです。その後、MEFはEditProfileのCTORのパラメータに、このクラスをマッピングすることができる必要があります。
ここで容器にエクスポート部を追加する例を示します。
var container = new CompositionContainer(catalog);
var instance1 = new EditProfileParameters();
// set property values from config or other resources
container.ComposeExportedValue(instance1);
container.ComposeParts(this);
が、ゲーム後半に、ここでMEFのあまり知られて機能を活用して、別のアプローチがあります:不動産の輸出
public class ObjectMother
{
[Export]
public static EditProfile DefaultEditProfile
{
get
{
var method = ConfigurationManager.AppSettings["method"];
var version = ConfigurationManager.AppSettings["version"];
return new EditProfile(method,version);
}
}
}
何の用途はこれが動作するためにObjectMotherために必要ありません、とは属性がEditProfileに必要ありません。