简体   繁体   English

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

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

I have a NuGet package in which I'm using ninject.我有一个 NuGet package 在其中我正在使用 ninject。 This NuGet package will be used by multiple applications and each of these applications have their own way of logging.这个 NuGet package 将被多个应用程序使用,每个应用程序都有自己的日志记录方式。 I want to be able to use a default logger implemented in my package, unless the developer who is using my NuGet binds his own implementation of my logging interface.我希望能够使用在我的 package 中实现的默认记录器,除非使用我的 NuGet 的开发人员绑定了他自己的日志接口实现。

So, let's say we have the following interface:所以,假设我们有以下接口:

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

Our NuGet package also provides its own implementation of the ILogger interface which is used by default:我们的 NuGet package 还提供了自己的默认使用的ILogger接口的实现:

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

In our NuGet package we have defined the following binding:在我们的 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: 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>();
}

If there is another implementation of the ILogger interface, I want to stop using the default ConsoleLogger and use the provided implementation instead.如果ILogger接口有另一个实现,我想停止使用默认的ConsoleLogger并改用提供的实现。 However, when I try something like this, I get the following exception:但是,当我尝试这样的事情时,我得到以下异常:

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

* ISomeService is a service whose implementation is depending on ILogger . * ISomeService是一项服务,其实现取决于ILogger This service cannot be activated anymore because I have messed something up when I called AddCustomBinding无法再激活此服务,因为我在调用AddCustomBinding时搞砸了

I have also tried the following:我还尝试了以下方法:

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

But the issue is still the same.但问题还是一样。 Does anyone know the possible solution for this?有谁知道可能的解决方案? Thanks!谢谢!

I found a proper solution to this problem.我找到了解决这个问题的正确方法。 The easiest way is to let the developers who are using my NuGet package implement an interface from my package which contains a method which loads custom bindings.最简单的方法是让使用我的 NuGet package 的开发人员从我的 package 中实现一个接口,该接口包含一个加载自定义绑定的方法。

Let's say I provide them with the following interface:假设我为他们提供了以下界面:

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

The developers who want to use their custom logger can then do something like this:想要使用自定义记录器的开发人员可以执行以下操作:

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. 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. When I gather all IModuleLoader implementations, I can call the LoadAssemblyBindings method to load all of the custom assemblies.当我收集所有IModuleLoader实现时,我可以调用LoadAssemblyBindings方法来加载所有自定义程序集。

Check the main idea behind this over here: https://www.codeproject.com/Articles/744862/Dependency-injection-in-class-libraries在此处查看其背后的主要思想: 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