31

我是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", 
                "to@email.com")));

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

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

5 回答 5

52

首先,您需要一个适合单身人士的生命周期管理器。ContainerControlledLifetimeManager

对于自定义初始化,您可以使用InjectionFactory

这使您可以编写任何初始化实体的代码。

Edit1:这应该有帮助

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

接着

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 );
于 2013-05-30T12:24:28.797 回答
15

你可以使用:

container.RegisterType<IEmail, Email>(new ContainerControlledLifetimeManager());
于 2013-05-30T12:33:00.193 回答
10

如果 IEmail 是一个没有依赖项(只是自定义参数)的单例,您可以自己新建它:

container.RegisterInstance<IEmail>(new Email("To Name", "to@email.com"));

这会将提供的实例注册为容器的单例。

然后你只需解决服务:

container.Resolve<OperationEntity>();

而且因为您正在解析具体类型,所以不需要注册。不过,如果您希望该服务也成为单例服务,则可以使用 ContainerControlledLifetimeManager 注册它,然后所有对解析的调用(或将其作为依赖项注入另一个类时)将返回相同的实例:

container.RegisterType<OperationEntity>(new ContainerControlledLifetimeManager());
于 2013-06-05T21:32:42.310 回答
0

您可以实现自己的单例类并从它扩展任何类。

public class MyClass : MonoBehaviour {

    private static MyClass _instance;

    public static MyClass Instance { get { return _instance; } }

    private void Awake()
    {
        if (_instance != null && _instance != this)
        {
            Destroy(this.gameObject);
        } else {
            _instance = this;
        }
    }
}
于 2021-06-08T16:34:14.727 回答
0

例如,您可以使用以下代码:

public class example : MonoBehaviour
{
    public static example instance;

    public void Start()
    {
        (!instance)
            instance = this;
    }
}
于 2020-10-09T13:50:15.533 回答