统一容器解析

本文关键字: | 更新日期: 2023-09-27 18:11:41

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

I get error如下:

解析依赖项失败,type = "UnityConsoleEx. "IBookService", name = "Database"。在解析时发生异常。异常是:InvalidOperationException -当前类型,UnityConsoleEx。IBookService是一个接口,不能被构造。您是否错过了类型映射?

At the time of the exception, the container was:
Resolving UnityConsoleEx.IBookService,Database

谁能指出我做错了什么?

统一容器解析

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

_container.RegisterType<IBookService, BookService>();

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

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

你需要解析不带名称的实例。

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

但是从你的例子中不清楚为什么你首先使用命名实例。如果你发布了你的服务的构造函数,如何使你的配置工作将会更清楚。

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

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

我认为,您尝试解决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"
    )
);

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

using Unity;
public interface IService
{
    void DoSomething();
}
public class ServiceA : IService
{
    public void DoSomething()
    {
        Console.WriteLine("ServiceA is doing something");
    }
}
public class ServiceB : IService
{
    public void DoSomething()
    {
        Console.WriteLine("ServiceB is doing something");
    }
}
public enum ServiceName
{
    ServiceA,
    ServiceB
}
public class DependencyResolver
{
    private static IUnityContainer _container;
    public static void Initialize(IUnityContainer container)
    {
        _container = container;
    }
    public static T Resolve<T>(ServiceName serviceName)
    {
        var serviceNameString = serviceName.ToString();
        return _container.Resolve<T>(serviceNameString);
    }
}
public static class Resolver
{
    public static IService Resolve(ServiceName serviceName)
    {
        return DependencyResolver.Resolve<IService>(serviceName);
    }
}
internal class Program
{
    private static void Main()
    {
        IUnityContainer container = new UnityContainer();
        // Register dependencies with names
        container.RegisterType<IService, ServiceA>(ServiceName.ServiceA.ToString());
        container.RegisterType<IService, ServiceB>(ServiceName.ServiceB.ToString());
        DependencyResolver.Initialize(container);
        // Example calls to ResolveService method with enums
        var serviceA = Resolver.Resolve(ServiceName.ServiceA);
        var serviceB = Resolver.Resolve(ServiceName.ServiceB);
        serviceA.DoSomething();
        serviceB.DoSomething();
        container.Dispose();
    }
}
相关文章:
  • 没有找到相关文章