繁体   English   中英

C#:如何在运行时使用 ninject 绑定我的接口的另一个实现?

[英]C#: How to bind another implementation of my interface at runtime using ninject?

我有一个 NuGet package 在其中我正在使用 ninject。 这个 NuGet package 将被多个应用程序使用,每个应用程序都有自己的日志记录方式。 我希望能够使用在我的 package 中实现的默认记录器,除非使用我的 NuGet 的开发人员绑定了他自己的日志接口实现。

所以,假设我们有以下接口:

public interface ILogger
{
    void Log(string message);
}

我们的 NuGet package 还提供了自己的默认使用的ILogger接口的实现:

internal class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine($"Console logger: {message}");
    }
}

在我们的 NuGet package 中,我们定义了以下绑定:

public void LoadAssemblyBindings(IKernel kernel)
{
    kernel.Bind<ILogger>().To<ConsoleLogger>().InSingletonScope();
}

Now I want to leave the possibility for the developer who is using my NuGet package to implement our ILogger interface and call a publicly available API in my NuGet package to replace our ILogger implementation with his own:

public void AddCustomBinding<T1, T2>()
    where T2 : T1
{
    this.kernel.Rebind<T1>().To<T2>();
}

如果ILogger接口有另一个实现,我想停止使用默认的ConsoleLogger并改用提供的实现。 但是,当我尝试这样的事情时,我得到以下异常:

Exception occurred: Ninject.ActivationException Error activating ISomeService
No matching bindings are available, and the type is not self-bindable.

* ISomeService是一项服务,其实现取决于ILogger 无法再激活此服务,因为我在调用AddCustomBinding时搞砸了

我还尝试了以下方法:

public void AddCustomBinding<T1, T2>(T2 newBinding)
    where T2 : T1
{
    return this.kernel.Rebind<T1>().ToConstant(newBinding);
}

但问题还是一样。 有谁知道可能的解决方案? 谢谢!

我找到了解决这个问题的正确方法。 最简单的方法是让使用我的 NuGet package 的开发人员从我的 package 中实现一个接口,该接口包含一个加载自定义绑定的方法。

假设我为他们提供了以下界面:

public interface IModuleLoader
{
    void LoadAssemblyBindings(IKernel kernel);
}

想要使用自定义记录器的开发人员可以执行以下操作:

public class ModuleLoader : IModuleLoader
{
    public void LoadAssemblyBindings(IKernel kernel)
    {
        kernel.Bind<ILogger>().To<FileLogger>().InSingletonScope();
    }
}

My ServiceLocator class is a static class which has a static constructor in which I can load all assemblies using reflection and check for IModuleLoader implementations. 当我收集所有IModuleLoader实现时,我可以调用LoadAssemblyBindings方法来加载所有自定义程序集。

在此处查看其背后的主要思想: https://www.codeproject.com/Articles/744862/Dependency-injection-in-class-libraries

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM