web-dev-qa-db-ja.com

Unityコンテナー解決

Unity Containerから始めたところ、私の登録は次のようになりました:

static void UnityRegister()
{
      _container = new UnityContainer();
      _container.RegisterType<IBook, Book>();
      _container.RegisterType<IBookRepository, BookRepository>("Book");
      _container.RegisterType<IBookService, BookService>();
      _container.RegisterType<IBookRepository, DatabaseRepository>("Database");
}

これを解決しようとすると:

var service = _container.Resolve<IBookService>("Database");

以下のエラーが発生します:

依存関係の解決に失敗しました。タイプ= "UnityConsoleEx.IBookService"、名前= "データベース"。例外が発生しました:解決中に。例外は次のとおりです:InvalidOperationException-現在のタイプUnityConsoleEx.IBookServiceはインターフェイスであり、構築できません。型マッピングがありませんか?

At the time of the exception, the container was:

Resolving UnityConsoleEx.IBookService,Database

誰かが私が間違っていることを指摘できますか?

9
Farukh

主な問題は、BookServiceの名前付きインスタンスを使用していないことです。

_container.RegisterType<IBookService, BookService>();

しかし、名前付きインスタンスで解決しようとしています。

var service = _container.Resolve<IBookService>("Database");

そのインスタンスを取得するには、名前なしで解決する必要があります。

var service = _container.Resolve<IBookService>();

しかし、そもそもなぜ名前付きインスタンスを使用しているのか、例からは明らかではありません。サービスのコンストラクターを投稿すると、構成を機能させる方法がより明確になります。

9
NightOwl888

私はそれを理解しました、サービスの名前付きインスタンスを作成し、そのようにコンストラクタを注入する必要がありました:

static void UnityRegister()
{
    _container = new UnityContainer();
    _container.RegisterType<IBook, Book>();
    _container.RegisterType<IBookRepository, BookRepository>();            
    _container.RegisterType<IBookRepository, DatabaseRepository>();

    _container.RegisterType<IBookService, BookService>("BookService", new InjectionConstructor(typeof(BookRepository)));
    _container.RegisterType<IBookService, BookService>("DatabaseService", new InjectionConstructor(typeof(DatabaseRepository)));
}

そして、以下のように解決してください:

var service = _container.Resolve<IBookService>("DatabaseService");
2
Farukh

BookServiceを解決しようとすると、パラメータとしてDatabaseRepositoryが含まれているはずです。あなたのやり方でそれを行うことはできません。

あなたはこのようにそれを行うことができます:

var service = _container.Resolve<IBookService>(new ParameterOverride("repository", _container.Resolve<IBookRepository>("Database")));

たぶん、より良い方法は、条件付きでリポジトリを一度登録することです:

  _container = new UnityContainer();
  _container.RegisterType<IBook, Book>();
  if (useDatabase)
  {
      _container.RegisterType<IBookRepository, DatabaseRepository>();
  }
  else
  {
      _container.RegisterType<IBookRepository, BookRepository>();
  }
  _container.RegisterType<IBookService, BookService>();

そして今、サービスを解決します。また、次のようにコンテナを構成できます。

_container.RegisterType<IBookService, BookService>(
    new InjectionConstructor(                        // Explicitly specify a constructor
        new ResolvedParameter<IBookRepository>("Database") // Resolve parameter of type IBookRepository using name "Database"
    )
);

これにより、単一のIBookServiceパラメーターを使用してコンストラクターを使用してIBookRepositoryを解決し、IBookRepositoryという名前でDatabaseを解決するようにコンテナーに指示します。

0
Backs