2011-06-28 16 views
21

Tüm iş sınıflarımın (onları komut ve sorgu sınıfları olarak adlandırıyorum) Windsor ile çözülmesini sağlayan bir birim sınaması oluşturmaya çalışıyorum. Aşağıdaki birim test var:Türleri yansıtma yoluyla geçerken <> c_DisplayClass türlerini nasıl filtrelerim?

[TestMethod] 
    public void Windsor_Can_Resolve_All_Command_And_Query_Classes() 
    { 
     // Setup 
     Assembly asm = Assembly.GetAssembly(typeof(IUnitOfWork)); 
     IList<Type> classTypes = asm.GetTypes() 
            .Where(x => x.Namespace.StartsWith("MyApp.DomainModel.Commands") || x.Namespace.StartsWith("MyApp.DomainModel.Queries")) 
            .Where(x => x.IsClass) 
            .ToList(); 

     IWindsorContainer container = new WindsorContainer(); 
     container.Kernel.ComponentModelBuilder.AddContributor(new SingletonLifestyleEqualizer()); 
     container.Install(FromAssembly.Containing<HomeController>()); 

     // Act 
     foreach (Type t in classTypes) 
     { 
      container.Resolve(t); 
     } 
    } 

Bu şu istisna ile başarısız:

No component for supporting the service MyApp.DomainModel.Queries.Organizations.OrganizationByRegistrationTokenQuery+<>c__DisplayClass0 was found 

Ben <>c__DisplayClass0 tip Derlenmekte Linq nedeniyle olduğunu anlıyoruz, fakat nasıl gömmek olmadan bu tür filtreleyebilirsiniz Linq sorgumdaki ad?

cevap

26

gibi dinamik sınıflar filtrelemek gerekiyor.

foreach (Type type in classTypes) 
{ 
    if (type.IsDefined (typeof (CompilerGeneratedAttribute), false)) 
     continue; 

    // use type... 
} 
+5

sınıfları yerine meclisleri düşünüyordum. Hayatı biraz daha basit hale getirmek için 'type.IsDefined' kullanabilirsiniz. –

+0

@Jon, Teşekkürler! İsDefined'i hatırlamalıyım ... Çok daha özlü! –

+0

Kod çalışıyor Yansımayı kullanarak çalışan VS2015 beri kırık olabilir! MethodCall'dan doğru İfade (bir 'List ') döndüren bir kod var. Şimdi bir <> c__DisplayClass36_0) .CS $ <> 8__locals1' döndürüyor. Bu bir 'MemberExpression' olduğunu unutmayın (bir değer olarak listeyi içeren bir ConstantExpression' idi)). Şimdi bu ek indirgemeyi takip etmeli ve daha sonra listemizi almak için "CS $ <> 8__locals1" alanının değerini almalıyım. –

4

[CompilerGenerated] özniteliğinin varlığını kontrol edin.

-1

Sen Bunları alınır System.Runtime.CompilerServices.CompilerGeneratedAttribute için her Tipi kontrol ediyorum bu

IList<Type> classTypes = asm.GetTypes() 
           .Where(x => x.Namespace.StartsWith("MyApp.DomainModel.Commands") || x.Namespace.StartsWith("MyApp.DomainModel.Queries")) 
           .Where(x => x.IsClass && !x.IsDynamic) 
           .ToList(); 
+0

sayılı. – SLaks

+0

System.Type bir IsDynamic özelliği yok – KallDrexx

+0

Haklısınız. – boca

11

Görünüşe iç içe sınıfları uygulanmış [CompilerGenerated] niteliğini alamadım: Kod şöyle görünür böylece

Sen, Type.IsDefined kullanabilirsiniz.

Bu senaryoyu ele almak için bu basit yöntemi çırptım.

bool IsCompilerGenerated(Type t) { 
    if (t == null) 
     return false; 

    return t.IsDefined(typeof(CompilerGeneratedAttribute), false) 
     || IsCompilerGenerated(t.DeclaringType); 
} 

bu davranış şu şekilde görünecektir sergileyen A sınıfı: Dinamik sınıf değil

class SomeClass { 
    void CreatesADisplayClass() { 
     var message = "foo"; 

     Action outputFunc =() => Trace.Write(message); 

     Action wheelsWithinWheels =() => 
     { 
      var other = "bar"; 

      Action wheel =() => Trace.WriteLine(message + " " + other); 
     }; 
    } 
} 
+2

Doğru cevap budur. Başparmak havaya! – Rookian

+0

Mono'da kabul edilen cevapla ilgili sıkıntı çektim çünkü Mono bazı şeyleri biraz farklı bir şekilde üretiyor (görünüşte). Bu mükemmel çalışıyor. Teşekkürler. –

İlgili konular