web-dev-qa-db-fra.com

Unity Singleton Code

Je suis nouveau dans nity et j'essaie d'écrire une logique Unity qui initialise et enregistre/résout une instance singleton de l'objet Email afin qu'elle puisse être utilisée sur plusieurs autres objets, un exemple ci-dessous étant OperationEntity .

Ainsi, lorsqu'il est enregistré, il remplit le singleton de messagerie avec certaines valeurs d'un fichier de configuration, puis chaque fois qu'une instance d'OperationEntity est créée (dans mon cas, il est en cours de désérialisation), il utilise ce même singleton de messagerie. Donc, toute ma logique client doit faire est de désérialiser OperationEntity et d'appeler PerformAction () - avec l'instance de messagerie prise en charge par Unity.

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

Toute aide serait appréciée pour faire fonctionner ce code Unity

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

Tout d'abord, vous avez besoin d'un bon gestionnaire de vie le ContainerControlledLifetimeManager est pour les singletons.

Pour l'initialisation personnalisée, vous pourriez probablement utiliser InjectionFactory

Cela vous permet d'écrire n'importe quel code qui initialise l'entité.

Edit1: cela devrait aider

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

puis

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

Edit2: Pour prendre en charge la sérialisation, vous devez reconstruire les dépendances après avoir désérialisé:

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

}

puis

OperationEntity entity = somehowdeserializeit;

// let unity rebuild your dependencies
container.BuildUp( entity );
44
Wiktor Zychla

Vous pouvez utiliser:

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

Si IEmail est un singleton sans dépendances (juste des arguments personnalisés), vous pouvez le créer vous-même:

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

Cela enregistrera l'instance fournie en tant que singleton pour le conteneur.

Ensuite, vous venez de résoudre le service:

container.Resolve<OperationEntity>();

Et comme vous résolvez un type concret, aucune inscription n'est requise. Néanmoins, si vous souhaitez que ce service soit également un singleton, vous pouvez l'enregistrer à l'aide de ContainerControlledLifetimeManager, puis tous les appels à résoudre (ou en l'injectant en tant que dépendance à une autre classe) renverront la même instance:

container.RegisterType<OperationEntity>(new ContainerControlledLifetimeManager());
7
Julian Dominguez