统一容器解析
本文关键字: | 更新日期: 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();
}
}