1

IoC を使用するように変換しようとしている多くの MVC アプリで使用される UserModel クラスがあります。

public class UserModel
{
    public string Login { get; set; }

    [DisplayName("Display Name")]
    public string DisplayName { get; set; }

    public static explicit operator UserModel(string userLogin)
    {
        IKernel IoC; // Where do I get this from?
        var ActiveDirRepo = IoC.Get<IActiveDirectoryRepository>();

        var User = ActiveDirRepo.FindById<ActiveDirectoryUser>(userLogin.ToUpper());

        return new UserModel()
        {
            Login = userLogin,
            DisplayName = User == null ? userLogin.ToUpper() : User.Name
        };
    }
}

からstringへの明示的な変換演算子がありUserModelます。以前はnewan を編集しActiveDirectoryRepositoryて使用していましたが、IoC/DI を使用したいと考えています。

私が今抱えている問題は、IoC コンテナー ( IKernel) を参照するにはどうすればよいですか?

UserModelオペレーターが作成しているため、外部から注入することはできません。

4

4 に答える 4

1

サービス ロケーター パターン フォームMicrosoft.Practices.ServiceLocationを使用できます。ninject が実装を提供しない場合は驚きます。そうでない場合は、実装するのは簡単です。

このコードでやりたいことを実行できるにもかかわらず、明示的な変換演算子を実装しないことを強くお勧めします。それは悪い習慣です。

于 2013-09-30T07:54:34.163 に答える
1

IoC に魔法はありません。場合によっては、アプリケーションの IoC コンテナーにアクセスできる開始点が必要な場合もあります。たとえば、次のようになります。

var ioc = Application.Instance.Container.Get<IActiveDirectoryRepository>();

コンテナーを介して作成されたオブジェクトには既に依存関係が注入されているため、どこからでも IoC コンテナーにアクセスする必要はありませんが、少なくとも一部のルート オブジェクトはコンテナーにアクセスする必要があります。

于 2013-09-30T07:56:16.077 に答える
1

理想的には、IoC コンテナーはアプリケーションの複合ルートにのみ存在する必要があります。それを念頭に置いて、クラスの依存関係を把握し、コンストラクターを介してそれらを注入することが重要です (コンストラクター DI を実行できない場合は、多くの IoC コンテナーが別の注入方法を提供します)。

IActiveDirectoryRepositoryここでは、UserModel を作成するために にアクセスする必要があります。ただし、作成メソッドexplicit operator UserModelは、インスタンス変数にアクセスできない静的メソッドです。残念ながら、依存性注入を使用して IoC を活用する能力が制限されるため、いくつかのアイデアを次に示します。

  • わかりやすい:サービス ロケーターパターンを使用します。のインスタンスを取得するには、サービス ロケータを使用しますIActiveDirectoryRepository。これは、現在の実装にうまく適応します (カーネル行をサービス ロケーターに交換します)。ただし、このパターンには欠点があります。最も顕著なのは、IActiveDirectoryRepositoryソースを内部化しているため、単体テストの効果が低下するという事実です。

  • Traditional :作成者を、そのコンストラクターを介してUserModel受け入れるファクトリーにします。IActiveDirectoryRepository次に、UserModelファクトリによって作成されたすべての は、提供された を使用しIActiveDirectoryRepositoryます。

    public sealed class UserFactory
    {
        private readonly IActiveDirecotryRepository repository;
        public UserFactory(IActiveDirectoryRepository repository)
        {
            this.repository = repository;
        }
    
        public UserModel CreateNewUser(string userLogin)
        {
            var User = repository.FindById<ActiveDirectoryUser>(userLogin.ToUpper());
            return new UserModel()
            {
                Login = userLogin,
                DisplayName = User == null ? userLogin.ToUpper() : User.Name
            } 
        }
    }
    
  • Fancy : クロージャーを作成し、作成IActiveDirectoryRepository者をファーストクラスの関数として渡します。

    static Func<string, UserModel> CreateFactory(IActiveDirectoryRepository repository)
    {
        return (userLogin) => 
        {
            var User = repository.FindById<ActiveDirectoryUser>(userLogin.ToUpper());
            return new UserModel()
            {
                Login = userLogin,
                DisplayName = User == null ? userLogin.ToUpper() : User.Name
            }   
        }
    }
    
于 2013-09-30T09:06:22.547 に答える