【发布时间】:2018-06-26 09:31:25
【问题描述】:
我在没有任何 IoC 容器的情况下为我的应用程序使用依赖注入模式。现在我决定使用一些 IoC 容器,因为我的 Composition Root 包含数千行代码,但我未能使其与我的类一起工作,这些类积极使用方差。比如下面这个界面
public interface IQuery<in TIn, out TOut>
{
IReadOnlyCollection<TOut> Get(TIn key);
}
和服务
public class FakeRepository : IQuery<object, string>
{
public IReadOnlyCollection<string> Get(object key)
{
return new[] { key.ToString() };
}
}
纯 DI 工作正常
IQuery<string, object> service = new FakeRepository();
但是 Autofac 和 DryIoc 都无法解决它。
service = autofacContainer.Resolve<IQuery<string, object>>(); // exception
service = dryIocContainer.Resolve<IQuery<string, object>>(); // exception
我需要一些额外的设置吗?是否有任何其他 IoC 容器支持这一点?我是不是要求太多了?
【问题讨论】:
-
如何在 autofac 或 dryloc 中注册实现类?标准的 dotnet 核心 ServiceCollection 有一个
.AddSingleton<TInterface, TImplementation>()方法,只有在查询到TInterface时才会解析实现类。还有一个.AddSingleton<TImplementation>助手,它只调用AddSingleton<TImplementation, TImplementation>()。 -
我打算使用基于约定的注册。
autofacBuilder.RegisterAssemblyTypes(typeof(FakeRepository).Assembly).AsImplementedInterfaces()dryIocContainer.RegisterMany(new[] { typeof(FakeRepository).Assembly }) -
协变和逆变的使用通常在解析服务集合时很有用,例如在发布事件时,超类型的处理程序也应该处理已发布的事件。但是,非收集解决方案(正如您所做的那样)对共同/对立差异的需求更为罕见,尤其是容器无法为您开箱即用的事情,因为它不知道如何在有多个可分配服务需要解决时做出响应。
-
您能否解释一下为什么在您的特定情况下需要协方差(与仅解析实际类型相比)并描述您希望容器如何处理重复分配,或者保证永远不会有任何重复/重叠?
-
我目前的服务遵循“返回最具体的类型,接受最通用的类型”的原则。例如
Authorizer(IAuthenticator<IIdentity> authenticator){...}和public class WindowsAuthenticator: IAuthenticator<WindowsIdentity>。要使用 IoC 容器,我必须将构造函数更改为Authorizer(IAuthenticator<WindowsIdentity> authenticator){...}。不仅工作量大,还让服务耦合度更高!
标签: c# autofac ioc-container dryioc