2010-01-05 21 views
36

MEF'in Yapıcı Enjeksiyon özelliğini anlamaya çalışıyorum. Kurucunun parametrelerini yüklemek için nasıl söylediğimi bilmiyorum. MEF Constructor Enjeksiyon

Bu

Ben burada

[ImportMany(typeof(BUsers))] 
public IEnumerable<BUsers> LoadBUsers { get; set; } 

Ben meclisleri ithal etmek kullanıyorum kodudur yüklemeye çalışıyorum özelliktir. İşte

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); 
} 

Sana yapıcı olmak ithalatın, parametreleri ImportingConstructor özelliğini kullandığınızda

[Serializable] 
[Export(typeof(BUsers))] 
public class EditProfile : BUsers 
{ 
    [ImportingConstructor] 
    public EditProfile(string Method, string Version) 
    {    
     Version = "2"; 
     Action = "Edit"; 
     TypeName = "EditProfile"; 
    } 

cevap

53

yüklemeye çalışıyorum sınıftır. Varsayılan olarak, içe aktardığınız (sözleşme adı), içe aktardığınız parametrenin veya özelliğin türüne dayanır. Bu durumda, hem ithalatınız için sözleşme türü dize, hem de birinci ve ikinci parametre arasında gerçek bir fark yoktur.

Yapılandırma değerlerini sağlamak için içe aktarma kullanmaya çalıştığınız anlaşılıyor; bu, ne için tasarlandığı gibi değil. Eğer istediğini yapmak almak için, bu gibi parametrelerin her biri için sözleşme adı geçersiz olmalıdır:

[ImportingConstructor] 
public EditProfile([Import("Method")] string Method, [Import("Version")] string Version) 
{ } 

Sonra kapta Yöntem ve Version ihracatını gerekir.

var container = new CompositionContainer(catalog); 
container.ComposeExportedValue("Method", "MethodValue"); 
container.ComposeExportedValue("Version", "2.0"); 
container.ComposeParts(this); 

(ComposeExportedValue aslında statik AttributedModelServices sınıfında tanımlanan bir uzantısı yöntemi olduğunu unutmayın.)

Bir yapılandırmasından bu değerleri okumak istiyorsanız: Bunu yapmanın bir yolu, doğrudan eklemek için adildir Bir çeşit dosya, kendi ihracat sağlayıcınızı oluşturabilir, bu da konfigürasyonu okur ve konteynırda ihracat olarak değerlerini sağlar.

Bunun üstesinden gelmenin alternatif bir yolu, yapılandırma değerlerine ada göre erişim sağlayan bir arabirim almak ve yapıcınızın gövdesinden gereksinim duyduğunuz değerleri almak olacaktır.

+0

Yeni olanı CodePlex'te yeni yükledim. ComposeExportedValue() yöntemi, CompositionContainer sınıfında değil. Nerede? –

+0

Sanırım bu yöntemi buldum. Yöntemin MethodContainer sınıfına genişletilmiş yöntem olarak tanımlandığı AttributedModelServices sınıfındadır. –

+1

@ David.Chu.ca Evet, ComposeExportedValue, AttributedModelServices sınıfında bir uzantı yöntemidir. –

23

Daniel'in çözümünü severim; Ancak, gördüğüm tek şey, özelleştirilmiş CTOR için aktör (CompopositionContrainer() öğesini oluşturan) ve [ImportingConstructor] ile İhracat bölümü arasındaki parametre adlarının sıkı bir şekilde eşleştirilmesidir. Örneğin, iki yöntemde "Yöntem" in iki tane eşleştirilmesi gerekir. Aktör ve İhracat bölümünün farklı projelerde olması durumunda İhracat bölümünü korumak zorlaşır.

Mümkünse, ikinci CTOR'u İhracat bölümü sınıfına eklerim. Örneğin: Yöntem ve Sürüm iki özellik:

[Export] 
public class EditProfileParameters{ 
    public string Method { get; set; } 
    public string Version { get; set; } 
} 

önemli nokta sınıfına İhracat özelliğini eklemektir

[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 sınıfı basit olmalıdır. Daha sonra MEF, bu sınıfı EditProfile'ın CTOR parametresine eşleyebilmelidir.

var container = new CompositionContainer(catalog); 
var instance1 = new EditProfileParameters(); 
// set property values from config or other resources 
container.ComposeExportedValue(instance1); 
container.ComposeParts(this); 
0

geç rağmen oyuna, burada bir az bilinen MEF özelliğini güçlendirir başka yaklaşım: Burada

kaba İhracat kısmını eklemek için örnektir Mülkiyet Exports

public class ObjectMother 
{ 
    [Export] 
    public static EditProfile DefaultEditProfile 
    { 
     get 
     { 
      var method = ConfigurationManager.AppSettings["method"]; 
      var version = ConfigurationManager.AppSettings["version"]; 

      return new EditProfile(method,version); 
     } 
    } 
} 

Bunun çalışması için ObjectMother için herhangi bir kullanım gerekmez ve EditProfile'da herhangi bir özellik gerekmez.

+0

Güzel özellik ama ne "EditProfile" herhangi bir ithalat içeriyorsa? Bu durumda kapta 'SatisfyImportsOnce' çağırmanız gerekir. Bu acıttı. Şu anda bu sorun için gerçek bir çözüm yok. –

+0

Bu durumda, EditProfile'ınızı elle örnekleyen bir fabrika oluşturuyoruz. EditProfile yapıcıda ek bağımlılıklar gerektiriyorsa, bu bağımlılıkları her zaman bir ImportingConstructor aracılığıyla Fabrika'ya getirebilirsiniz. EditProfile'a ek bağımlılıklar eklerseniz, uygulamanızda bu kurucuya yapılan tek referans olduğunu ve derleme zamanı hataları alacağınızı belirtmeliyim. Bu adil bir ticaret, IMHO. – bryanbcook