web-dev-qa-db-fra.com

Unity Container Resolve

Je viens de commencer avec Unity Container et mon enregistrement ressemble à ceci:

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

Maintenant, quand j'essaie de résoudre cela: 

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

J'ai l'erreur ci-dessous: 

La résolution de la dépendance a échoué, tapez = "UnityConsoleEx.IBookService", name = "Base de données". Une exception s'est produite pendant: la résolution. L'exception est: InvalidOperationException - Le type actuel, UnityConsoleEx.IBookService, est une interface et ne peut pas être construit. Il vous manque un mappage de type?

At the time of the exception, the container was:

Resolving UnityConsoleEx.IBookService,Database

Quelqu'un peut-il indiquer ce que je fais mal? 

6
Farukh

Le problème principal est que vous n'utilisez pas d'instance nommée pour votre BookService.

_container.RegisterType<IBookService, BookService>();

Mais vous essayez de résoudre avec une instance nommée.

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

Vous devez résoudre sans nom pour obtenir cette instance.

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

Cependant, votre exemple ne permet pas de comprendre pourquoi vous utilisez des instances nommées. Si vous postez les constructeurs de vos services, vous verrez plus clairement comment faire fonctionner votre configuration.

9
NightOwl888

Je l'ai compris, j'avais besoin de créer une instance nommée pour le service et d'injecter le constructeur, en tant que tel:

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)));
}

Et résolvez-le comme ci-dessous:

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

Je pense que vous essayez de résoudre BookService avec devrait contenir DatabaseRepository en tant que paramètre. Vous ne pouvez pas le faire à votre façon.

Vous pouvez le faire comme ça:

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

Peut-être qu'un meilleur moyen consiste à enregistrer le référentiel une fois, conditionnellement:

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

Et maintenant, résolvez le service. Vous pouvez également configurer votre conteneur de la manière suivante:

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

Cela indiquera au conteneur de résoudre IBookService à l'aide du constructeur avec le paramètre unique IBookRepository et de résoudre IBookRepository avec le nom Database.

0
Backs