C# Unity 单例代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16835728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unity Singleton Code
提问by Bern
I'm new to Unityand am trying to write some Unity logic which initialises and register/resolves a singleton instance of the Email object so that it can be used across several other objects, one example below being OperationEntity.
我是Unity 的新手,正在尝试编写一些 Unity 逻辑,用于初始化和注册/解析电子邮件对象的单例实例,以便它可以跨多个其他对象使用,下面的一个示例是 OperationEntity。
So when it's registered it populates the Email singleton with some values from a config file, then whenever an instance of OperationEntity is created (in my case it's being deserialized) it uses that same Email singleton. So all my client logic needs to do is deserialize OperationEntity and call PerformAction() - with the email instance taken care of by Unity.
因此,当它注册时,它会使用配置文件中的一些值填充电子邮件单例,然后每当创建 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();
}
}
Any help would be appreciated in getting this Unity code to work
任何帮助使此 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));
}
采纳答案by Wiktor Zychla
First, you need a proper lifetime managerthe ContainerControlledLifetimeManageris for singletons.
首先,你需要一个适当的寿命管理的ContainerControlledLifetimeManager是单身。
For custom initialization, you could probably use InjectionFactory
对于自定义初始化,您可能可以使用 InjectionFactory
This lets you write any code which initializes the entity.
这使您可以编写初始化实体的任何代码。
Edit1: this should help
Edit1:这应该有帮助
public static void Register(IUnityContainer container)
{
container
.RegisterType<IEmail, Email>(
new ContainerControlledLifetimeManager(),
new InjectionFactory(c => new Email(
"To Name",
"[email protected]")));
}
and then
进而
var opEntity = container.Resolve<OperationEntity>();
Edit2: To support serialization, you'd have to rebuild dependencies after you deserialize:
Edit2:要支持序列化,您必须在反序列化后重建依赖项:
public class OperationEntity
{
// make it public and mark as dependency
[Dependency]
public IEmail _email { get; set;}
}
and then
进而
OperationEntity entity = somehowdeserializeit;
// let unity rebuild your dependencies
container.BuildUp( entity );
回答by aquaraga
You could use:
你可以使用:
container.RegisterType<IEmail, Email>(new ContainerControlledLifetimeManager());
回答by Julian Dominguez
If IEmail is a singleton with no dependencies (just custom arguments), you can new it up yourself:
如果 IEmail 是一个没有依赖项(只有自定义参数)的单例,你可以自己新建它:
container.RegisterInstance<IEmail>(new Email("To Name", "[email protected]"));
That will register the supplied instance as a singleton for the container.
这会将提供的实例注册为容器的单例。
Then you just resolve the service:
然后你只需解析服务:
container.Resolve<OperationEntity>();
And because you are resolving a concrete type, there is no registration required. Nevertheless, if you would like that service to also be a singleton, you can register it using ContainerControlledLifetimeManager and then all calls to resolve (or when injecting it as a dependency to another class) will return the same instance:
并且因为您正在解析一个具体类型,所以不需要注册。然而,如果您希望该服务也成为单例,您可以使用 ContainerControlledLifetimeManager 注册它,然后所有解析调用(或将其作为依赖项注入另一个类时)将返回相同的实例:
container.RegisterType<OperationEntity>(new ContainerControlledLifetimeManager());

