5

Bir BaseClass ile çok sayıda sınıf (300+) içeren bir derleme var ve bir arabirim ile genel bir sınıf kaydetmek istiyorum.Genel sınıfları Unity ile bir adla dinamik olarak nasıl kaydedebilirim?

Birlik ile, arabirimin bir dizi nesnesini çözmek istiyorsanız, {Ad Adı ile kayıt olmanız gerekir). Otomatik olarak MainViewModel içinde bir dizi nesne istiyorum.

Bunu yansımayla otomatikleştirmenin bir yolu var mı? Herhangi bir öneriniz var mı?

Örnek (sözde): elle

public class BaseClass 
{ 
    public void doFoo(); 
} 

public ClassNumber001 : BaseClass 
{ 
} 
public ClassNumber002 : BaseClass 
{ 
} 

public interface ISuperman 
{ 
} 

public class Superman : ISuperman where T : BaseClass 
{ 
} 

public MainViewModel(IEnumerable<ISuperman> lotsofSuperman) 
{ 
} 

Çalışma örneği:

container.RegisterType<ISuperman, Superman <ClassNumber001>>("ClassNumber001"); 
container.RegisterType<ISuperman, Superman <ClassNumber002>>("ClassNumber002"); 
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>(); 
+0

Yansıma ile yapılması zorunlu mudur? 3.x üzerinde hangi Unity sürümünü kullanıyorsunuz? – gastonmancini

+0

Hayır, zorunlu değil, daha önce de kullandım çünkü yansımayı kullandım. (300 sınıfı bulmak için) Unity 3.5.1404.0 kullanıyorum. – Tim

cevap

0

Bu yapılabilecek bazı yollar vardır. Biri, tipin tanımlandığı XML'i kullanarak, MyClass ve IMyClass diyelim ve çalışma sırasında kullanılabilir meclisleri temel alarak çözer. Ancak benim görüşüme göre daha iyi bir yaklaşım, bağımlılıkları yükleme sorumluluğunu devredebileceğiniz bir proje oluşturmak olacaktır.

 public class MyClass : IMyClass 
    { 
     private readonly IUnityContainer _container; 

     #ctor 
     // initialie the container through the constructor 

     public void DoWork<Interface, Class>() where Class: Interface 
     { 
      _container.RegisterType<Interface, Class>(
      //TODO: You can setup the container lifecycle which can be transient 
      // or singleton or custom based on your project requirement 
      ) 
     } 
    } 

Şimdi kim olduğunu gerçekleştirmek gerekiyor hangisi sınıf enjekte edilebilir kendisi kap ve bağımlılık kayıtlı almak için bu arayüz IMyClass çağırabilir kendisi kayıt gerekir:

bir sınıf şöyle oluşturmak Diyelim görev.

1

Evet, yansımanın tamamını kolayca kullanmanız gerekecek, tüm eşleştirmeleri oluşturun. Unity 3'ü kullandığınız için, sınıfları kaydetmede yardım (daha ağır kaldırma ile) sağlamak için Registration by Convention'dan yararlanabilirsiniz. Hepimizin olsun Yukarıdaki kodda

IUnityContainer container = new UnityContainer(); 

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t)) 
     .Select(t => typeof(Superman<>).MakeGenericType(t)), 
    t => new Type[] { typeof(ISuperman) }, 
    t => t.GetGenericArguments().First().Name, 
    WithLifetime.Transient); 

container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>(); 

container.Resolve<MainViewModel>(); 

:

public abstract class BaseClass 
{ 
    public abstract void DoFoo(); 
} 

public class ClassNumber001 : BaseClass 
{ 
    public override void DoFoo() 
    { 
     Console.WriteLine("001 Foo"); 
    } 
} 

public class ClassNumber002 : BaseClass 
{ 
    public override void DoFoo() 
    { 
     Console.WriteLine("002 Foo"); 
    } 
} 

public interface ISuperman 
{ 
    void Do(); 
} 

public class Superman<T> : ISuperman where T : BaseClass 
{ 
    private T baseClass; 

    public Superman(T baseClass) 
    { 
     this.baseClass = baseClass; 
    } 

    public void Do() 
    { 
     this.baseClass.DoFoo(); 
    } 
} 

public class MainViewModel 
{ 
    public MainViewModel(IEnumerable<ISuperman> lotsofSuperman) 
    { 
     foreach(ISuperman superman in lotsofSuperman) 
     { 
      superman.Do(); 
     } 
    } 
} 

Sonra bütün jeneriği kayıt Kongre tarafından tescil kullanın: Ben senin sözde kodu alınır ve gerçek koduna tercüme ettik

BaseClass'dan devralıp sınıflar ve Superman<> türünde bir yapı oluşturup kodunu BaseClass adını kullanarak eşleştirin.RegisterTypes çağrı her BaseClass çağrısında RegisterType eşit olacaktır:

001 Foo
002: Sonra

container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001"); 
container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002"); 

MainViewModel hepsi ISuperman örneklerini yineler ve yazdıran bir yöntemini çağırır çözüldüğünde Superman<ClassNumber001> ve: biz 2 ISuperman örnekleri enjekte gösteren foo

.

Temel Sınıflar için belirli kayıtlara (örneğin, varsayılan olmayan ömür boyu yönetici) ihtiyacınız varsa, bunları kaydetmek için sözleşmeyi kullanarak da kullanabilirsiniz).

İlgili konular