簡體   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