web-dev-qa-db-ja.com

Unityシングルトンコード

私は nity が初めてで、Emailオブジェクトのシングルトンインスタンスを初期化および登録/解決する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();
    }
}

この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

まず、適切な lifetime manager が必要です。ContainerControlledLifetimeManagerはシングルトン用です。

カスタム初期化には、おそらく InjectionFactory を使用できます

これにより、エンティティを初期化するコードを記述できます。

編集1:これは役立つはずです

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 );
44
Wiktor Zychla

次を使用できます。

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

IEmailが依存関係のないシングルトン(カスタム引数のみ)である場合、それを自分で更新できます。

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

これにより、提供されたインスタンスがコンテナのシングルトンとして登録されます。

次に、サービスを解決します。

container.Resolve<OperationEntity>();

また、具体的な型を解決しているため、登録は必要ありません。それでも、そのサービスをシングルトンにしたい場合は、ContainerControlledLifetimeManagerを使用して登録すると、解決するすべての呼び出し(または別のクラスへの依存関係として注入するとき)は同じインスタンスを返します。

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