Подтвердить что ты не робот

Unity Singleton Code

Я новичок в Unity и пытаюсь написать некоторую логику Unity, которая инициализирует и регистрирует/решает один экземпляр объекта электронной почты, чтобы он мог можно использовать для нескольких других объектов, один из примеров ниже - OperationEntity.

Таким образом, когда он регистрируется, он заполняет одноэлемент электронной почты некоторыми значениями из файла конфигурации, тогда всякий раз, когда создается экземпляр OperationEntity (в моем случае он десериализован), он использует тот же самый сингл электронной почты. Таким образом, вся моя клиентская логика должна выполнять десериализацию OperationEntity и вызывать PerformAction() - с экземпляром электронной почты, позаботившимся об 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();
    }
}

Любая помощь будет оценена при использовании этого кода 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));
    }
4b9b3361

Ответ 1

Во-первых, вам нужен правильный пожизненный менеджер ContainerControlledLifetimeManager для одиночных одиночек.

Для пользовательской инициализации вы, вероятно, можете использовать InjectionFactory

Это позволяет вам писать любой код, который инициализирует объект.

Edit1: это должно помочь

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

а затем

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

Edit2: для поддержки сериализации вам придется перестроить зависимости после десериализации:

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

}

а затем

OperationEntity entity = somehowdeserializeit;

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

Ответ 2

Вы можете использовать:

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

Ответ 3

Если IEmail - это синглтон без зависимостей (только пользовательские аргументы), вы можете его обновить самостоятельно:

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

Это зарегистрирует предоставленный экземпляр в качестве одиночного элемента для контейнера.

Затем вы просто разрешите обслуживание:

container.Resolve<OperationEntity>();

И поскольку вы решаете конкретный тип, регистрация не требуется. Тем не менее, если вы хотите, чтобы эта служба также была одиночной, вы можете зарегистрировать ее с помощью ContainerControlledLifetimeManager, а затем все вызовы для решения (или при вводе ее как зависимости другому классу) вернут один и тот же экземпляр:

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