简短的问题是:鉴于图书馆保证使用特定的IOC容器作为其内部,当应用程序使用该库时,给定应用程序保证使用IOC容器连接其依赖关系,如果这两个容器不同,则如何一起玩得好吗?
方案是,应用程序具有依赖于库中类型的类.因此,当应用程序容器尝试构建此类时,它需要知道如何解析库中的类型.
这是一个冗长的问题:
这个问题似乎确实在SO之前以不同的形式和形式被问过,但我似乎无法找到我需要的答案,因此我将使用一个假设的_over_simplified_具体示例.我们希望编写一个用于日志记录的库,用户可以在其解决方案中将其作为包包含在内,以便开箱即用地获取日志记录功能.库公开的公共接口是..
public interface ILogger {}
public interface ITarget {}
具体实现是
internal class Logger: ILogger { public Logger(ITarget target) {}}
internal class FileTarget : ITarget {}
要求是,如果用户包含我们的包并定义具有类型属性的类ILogger或具有类型的ctor参数,ILogger那么我们的库负责将该接口的具体实现注入到用户定义的类中.默认情况下,注入的logger将转到文件系统进行日志记录,因为ITarget注入实现的默认ILogger实现是FileTarget由我们的库实现的.
如果用户决定编写实现该ITarget接口的类,那么我们的库将使用它来注入Logger类而不使用其默认FileTarget实现.
所以我想展示的是,他们在这里是一个双向依赖.
我们的库依赖于用户的程序集,因为它需要扫描用户的程序集以加载任何扩展点(即ITarget实现),并在任何默认实现之前将它们注入到自己的对象中.
用户的程序集依赖于库,因为如果用户选择将ILogger接口定义为依赖关系的类,那么该用户对象应该获得对我们的库在运行时提供的该接口的具体引用.
简单的解决方案是,如果用户和我们的库都使用相同的IOC容器,那么问题就解决了.但这是一个强有力的假设.我想做的是
到目前为止这么好,它是完全可以实现的,但这里是棘手的部分.
我几乎想要在库中使用这样的接口定义某种子容器功能
public interface IDependencyResolvingModule { T Get<T>(); []T GetAll<T>(); }
并提供一个实现,它使用我们库的容器选择(即Ninect)来解析上面定义的两个方法中请求的类型.
我希望用户的IOC容器具有一些功能,如果它不能解析依赖关系(即一个ILogger),它应该挂钩到IDependencyResolvingModule实现并询问依赖.
这样我们的库就可以使用它选择的IOC容器,并且用户的代码有办法解决其IOC容器没有任何线索的依赖关系.如果IOC容器有一些如何提供功能来注册IDependencyResolverModules …