Unity 容器解析

Unity Container Resolve

我刚开始使用 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");

我收到以下错误:

Resolution of the dependency failed, type = "UnityConsoleEx.IBookService", name = "Database". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, UnityConsoleEx.IBookService, is an interface and cannot be constructed. Are you missing a type mapping?

At the time of the exception, the container was:

Resolving UnityConsoleEx.IBookService,Database

谁能指出我做错了什么?

我认为,您尝试使用应该包含 DatabaseRepository 作为参数来解析 BookService。你不能按照你的方式去做。

你可以这样做:

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

这将告诉容器使用带有单个 IBookRepository 参数的构造函数解析 IBookService,并使用名称 Database.

解析 IBookRepository

主要问题是您没有为您的 BookService 使用命名实例。

_container.RegisterType<IBookService, BookService>();

但是您正在尝试使用命名实例进行解析。

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

您需要在没有名称的情况下解析才能获取该实例。

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

但是从您的示例中并不清楚您首先使用命名实例的原因。如果您 post 是您服务的构造者,那么如何使您的配置工作会更加清楚。

我明白了,我需要为服务创建命名实例并注入构造函数,如下所示:

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