2013-05-30 21 views
14

Unity için yeniyim ve E-posta nesnesinin tekil bir örneğini başlatan ve kaydeden/bunları çözen bazı Unity mantığı yazmaya çalışıyorum; böylece başka bir nesne üzerinde kullanılabilir, bunun altında bir örnek OperationEntity'dir.Unity Singleton Kodu

Kayıt edildiğinde, e-posta tekilini bir yapılandırma dosyasındaki bazı değerlerle doldurur, ardından bir OperationEntity örneği oluşturulduğunda (benim durumumda serileştirilir) aynı E-posta tekilini kullanır. Bu nedenle benim tüm istemci mantığımın, OperationEntity'yi deserialize etmesi ve PerformAction'ı() - Unity tarafından bakılan e-posta örneğiyle çağırması gerekiyor.

public interface IEmail 
{ 
    string FromName { get; set; } 
    string FromEmailAddress { get; set; } 
} 

public class Email : IEmail 
{ 
    public string FromName { get; set; } 
    public string FromEmailAddress { get; set; } 

    public Email(string fromName, string fromEmailAddress) 
    { 
     FromName = fromName; 
     FromEmailAddress = fromEmailAddress; 
    } 
} 

public class OperationEntity 
{ 
    private readonly IEmail _email; 

    public int OperationId { get; set; } 
    public string OperationName { get; set; } 
    public string ToAddress { get; set; } 

    public OperationEntity(IEmail email) 
    { 
     _email = email; 
    } 

    public void PerformAction() 
    { 
     _email.ToAddress = ToAddress; 
     _email.Body = "Some email body"; 
     _email.Deliver(); 
    } 
} 

Herhangi bir yardım

public static void Register(IUnityContainer container) 
    { 
     container 
      .RegisterType<IEmail, Email>(
      new InjectionFactory(c => new Email(
       "To Name", 
       "[email protected]"))); 

     var email = container.Resolve<IEmail>(); 

     container.RegisterType<OperationEntity>(
      "email", new ContainerControlledLifetimeManager(), 
      new InjectionConstructor(email)); 
    } 
+0

Bunu kurmak için C# Unity koduyla ilgili yardım arıyordum. – Bern

+0

Belki [Singleton hakkında wiki] (http://wiki.unity3d.com/index.php/Singleton) biraz yardımcı olabilirdi. – cregox

+0

@cregox Bu, bir grafik kütüphanesi olan Unity3d'ye bir bağlantıdır. Bu, [Birlik kabı] (https://msdn.microsoft.com/en-us/library/ff647202.aspx), DI çerçevesi ile ilgili bir sorudur. – Andy

cevap

27

İlk işe bu Birlik kodunu almak mutluluk duyacağız, uygun bir lifetime managerContainerControlledLifetimeManager singletons içindir gerekir.

özel başlatma için, muhtemelen Bu varlık başlatır herhangi bir kod yazmak sağlayan InjectionFactory

kullanabilirsiniz.

Edit1: Bu

public static void Register(IUnityContainer container) 
{ 
    container 
     .RegisterType<IEmail, Email>(
     new ContainerControlledLifetimeManager(), 
     new InjectionFactory(c => new Email(
      "To Name", 
      "[email protected]"))); 
} 

ve yardımcı olmalıdır sonra

var opEntity = container.Resolve<OperationEntity>(); 

Edit2: seri desteklemek için, size serisini sonra bağımlılıkları yeniden olurdu:

public class OperationEntity 
{ 
    // make it public and mark as dependency 
    [Dependency] 
    public IEmail _email { get; set;} 

} 

ve daha sonra

OperationEntity entity = somehowdeserializeit; 

// let unity rebuild your dependencies 
container.BuildUp(entity); 
+0

Bir e-posta örneğini çözmek için ikinci bağlantıdan mantığı kullandım, ancak OperationEntity'nin bu örneği kurucusunda kullanmasını sağlamak için nasıl giderim? Container.RegisterType (yeni InjectionConstructor (email)) çalıştı; ama şans yok. – Bern

+0

ContainerControlledLifetimeManager'ı kullanırsanız, yalnızca tek kişilik öğe diğer sınıfların yapıcılarına her zaman enjekte edilir. –

+0

Önerilerimi kullanarak yukarıdaki kodumu ekledim, maalesef OperationEntity yapıcısındaki e-posta örneği için hala boş bir değer elde ediyorum. Düşüncelerin için seni rahatsız edebilir miyim? – Bern

11

Sen kullanabilirsiniz:

container.RegisterType<IEmail, Email>(new ContainerControlledLifetimeManager()); 
6

IEmail hiçbir bağımlılıkları (sadece özel argümanlar) ile bir tekil ise, olabildiğince yeni o kadar kendinizi: olarak temin örneğini kaydedecektir

container.RegisterInstance<IEmail>(new Email("To Name", "[email protected]")); 

konteyner için bir tek kişilik.

Sonra sadece hizmet çözmek:

container.Resolve<OperationEntity>(); 

Ve eğer bir beton türü çözme, çünkü herhangi bir kayıt gerekmiyor yoktur. Ayrıca a tek olmak için bu hizmeti istiyorsanız Yine de, sen ContainerControlledLifetimeManager kullanarak kayıt olabilirsiniz ve sonra tüm çözmek için çağırır (veya başka bir sınıfa bir bağımlılık olarak enjekte olduğunda) aynı örneği döndürür:

container.RegisterType<OperationEntity>(new ContainerControlledLifetimeManager()); 
+1

Bunun için teşekkürler. Sonunda, asıl sorun olan OperationEntity'nin serileştirilmesiydi ve bu yaklaşımın buna uygun olduğundan emin değilim. Serileştirmeden sonra kodun ihtiyacı unityContainer.BuildUp (OperationEntity); – Bern