C# 统一单例码
我是新手,正在尝试编写一些Unity逻辑来初始化和注册/解析电子邮件对象的单例实例,以便它可以跨多个其他对象使用,下面的一个例子是OperationEntity 因此,当它被注册时,它用配置文件中的一些值填充电子邮件单例,然后每当创建OperationEntity实例时(在我的例子中,它被反序列化),它都使用相同的电子邮件单例。因此,我的客户端逻辑需要做的就是反序列化OperationEntity并调用PerformAction()——电子邮件实例由Unity负责C# 统一单例码,c#,unity-container,C#,Unity Container,我是新手,正在尝试编写一些Unity逻辑来初始化和注册/解析电子邮件对象的单例实例,以便它可以跨多个其他对象使用,下面的一个例子是OperationEntity 因此,当它被注册时,它用配置文件中的一些值填充电子邮件单例,然后每当创建OperationEntity实例时(在我的例子中,它被反序列化),它都使用相同的电子邮件单例。因此,我的客户端逻辑需要做的就是反序列化OperationEntity并调用PerformAction()——电子邮件实例由Unity负责 public interfac
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();
}
}
如果您有任何帮助,我们将不胜感激
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));
}
公共静态无效寄存器(IUnityContainer容器)
{
容器
.RegisterType(
新注入工厂(c=>新电子邮件(
“命名”,
"to@email.com")));
var email=container.Resolve();
container.RegisterType(
“电子邮件”,新的ContainerControlled LifetimeManager(),
新注入构造函数(电子邮件);
}
首先,您需要一个合适的容器控制生命周期管理器
适用于单身人士
对于自定义初始化,您可能可以使用
这允许您编写初始化实体的任何代码
编辑1:这应该会有帮助
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>();
OperationEntity entity = somehowdeserializeit;
// let unity rebuild your dependencies
container.BuildUp( entity );
您可以使用:
container.RegisterType<IEmail, Email>(new ContainerControlledLifetimeManager());
container.RegisterType(新ContainerControlledLifetimeManager());
如果IEmail是没有依赖项(只有自定义参数)的单例邮件,您可以自己创建:
container.RegisterInstance<IEmail>(new Email("To Name", "to@email.com"));
container.RegisterInstance(新电子邮件(“收件人”),“to@email.com"));
将提供的实例注册为容器的单例
然后您只需解析服务:
container.Resolve<OperationEntity>();
container.Resolve();
由于您正在解析一个具体类型,因此不需要注册。不过,如果您希望该服务也是一个单例服务,可以使用ContainerControlled LifetimeManager注册它,然后所有解析调用(或将其作为依赖项注入另一个类时)都将返回相同的实例:
container.RegisterType<OperationEntity>(new ContainerControlledLifetimeManager());
container.RegisterType(新ContainerControlledLifetimeManager());
例如,您可以使用以下代码:
public class example : MonoBehaviour
{
public static example instance;
public void Start()
{
(!instance)
instance = this;
}
}
您可以实现自己的单例类并扩展它的任何类
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;
}
}
}
我正在寻找一些有关连接此功能所需的C#Unity代码的帮助。可能有一些帮助。@cregox是指向Unity3d的链接,一个图形库。这是一个关于DI框架的问题。@Andy你是说这个链接完全没有帮助吗?到目前为止,我仍在学习关于单例和DI的知识,所以如果这真的是完全不相关的话,那就很高兴知道了@在这种情况下,我认为它没有那么有用;对于大多数DI容器,您可以配置插件类型的生存期,以便只有一个实例,但消费者实际上并不知道他们使用的是单实例。例如,在.Net中,我使用了一个接口来抽象.config文件的读取。需要配置的实例通过ctor注入引用接口,这与正常情况类似,但由于实现只是包装了一个静态的线程安全方法,因此我将其配置为单例,因此DI框架实际上只创建了对象的一个实例。我使用第二个链接中的逻辑来解析电子邮件实例,但是如何确保OperationEntity在其构造函数中使用该实例呢?我尝试了container.RegisterType(新注入构造函数(电子邮件));但是运气不好。如果您使用ContainerControlled LifetimeManager,唯一的单例实体将始终注入其他类的构造函数中。我在上面使用您的建议包含了我的代码,不幸的是,我在OperationEntity构造函数中仍然得到电子邮件实例的空值,因此我猜我错过了一些内容。我可以麻烦你考虑一下吗。谢谢Wiktor,到目前为止,我对你感激地提供的更新代码的唯一问题是,当我反序列化OperationEntity的一个实例,并调用其构造函数时,电子邮件实例仍然为空。因此,对PerformAction()方法的后续调用具有空\u电子邮件。非常感谢您的耐心和帮助,在您的帮助下,我成功地完成了任务。谢谢您的帮助。最后,OperationEntity的反序列化才是主要问题,我不确定这种方法能否解决这个问题。反序列化后需要的代码是unityContainer.Building(OperationEntity);实际上,这是可行的,但您必须使用Microsoft.Practices.Unity添加
,但是当更新到版本5.8.11时,即使添加此名称空间也不再有效,我找不到该方法。如果你有任何想法,请你提供一个投资多一点的时间时,回答将是好的。例如,我非常确定基类被称为monobhavior
,而不是monobhavior
。
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;
}
}
}