c# - 是否可以通过 IContext 解析 Ninject 工厂方法中的调用者实例?

标签 c# .net ninject

我想这是我想要实现的一个非常简单的场景。

我只是想知道是否可以在 Ninject 工厂方法中获取调用实例。

public static class Program
{
    public static void Main(params string[] args)
    {
        var standardKernelCaller = new StandardKernelCaller();

        standardKernelCaller.Call();

        Console.ReadKey();
    }
}

public interface IA
{
}

public class A : IA
{
    public int Parameter { get; }

    public A(int parameter)
    {
        Parameter = parameter;
    }
}

public class Module : NinjectModule
{
    public override void Load()
    {
        Bind<IA>().ToMethod(Create);
    }

    private static A Create(IContext context)
    {
        var number = // resolve the caller (StandardKernelCaller) Magic Number using context...
        return new A(number);
    }
}

public class StandardKernelCaller
{
    public const int MagicNumber = 42;

    public void Call()
    {
        var standardKernel = new StandardKernel(new Module());

        var stuff = standardKernel.Get<IA>();
    }
}

我不太确定这是否是一个好的做法。目前在相关的生产代码中我正在使用类似的东西:

public abstract class BusinessApiController<TBusinessLogic> : ApiController
    where TBusinessLogic : class, IBusinessLogic
{
    protected TBusinessLogic BusinessLogic { get; private set; }

    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);

        BusinessLogic = CreateBusinessLogic();
    }

    protected virtual TBusinessLogic CreateBusinessLogic()
    {
        var businessLogic = BusinessLogicFactory.Create<TBusinessLogic>(this.GetOwinContext());

        return businessLogic;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (BusinessLogic != null)
            {
                BusinessLogic.Dispose();
                BusinessLogic = null;
            }
        }

        base.Dispose(disposing);
    }
}


public abstract class BusinessController<TBusinessLogic> : Controller
    where TBusinessLogic : class, IBusinessLogic
{
    protected TBusinessLogic BusinessLogic { get; private set; }

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);

        BusinessLogic = CreateBusinessLogic();
    }

    protected virtual TBusinessLogic CreateBusinessLogic()
    {
        var businessLogic = BusinessLogicFactory.Create<TBusinessLogic>(this.GetOwinContext());

        return businessLogic;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (BusinessLogic != null)
            {
                BusinessLogic.Dispose();
                BusinessLogic = null;
            }
        }

        base.Dispose(disposing);
    }
}

但我不太喜欢下面工厂中硬编码的“owinContext”参数名称:

public static class BusinessLogicFactory
{
    // Potentially obsolete readonly / configuration kernel in upcoming Ninject versions
    private static readonly StandardKernel StandardKernel = new StandardKernel(new BusinessLogicsNinjectModule());

    public static TBusinessLogic Create<TBusinessLogic>(IOwinContext owinContext)
    {
        // Potential refactoring: get the argument name via expression binding or use Ninject providers
        var businessLogic = StandardKernel.Get<TBusinessLogic>(new ConstructorArgument("owinContext", owinContext));

        return businessLogic;
    }
}

这是 Ninject 模块的简化版本的示例:

public class BusinessLogicsNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<IUserManagementBusinessLogic>().To<UserManagementBusinessLogic>();
        Bind<IAppointmentManagementBusinessLogic>().To<AppointmentManagementBusinessLogic>();
        Bind<ITeamAppointmentManagementBusinessLogic>().To<TeamAppointmentManagementBusinessLogic>();
    }
}

顺便说一句,如果有更好的业务逻辑注入(inject)方法或更好的整体设计,我很想了解更多信息。

最佳答案

首先,让我回答你的第一个问题: 在您的示例中,无法确定 StandardKernelCaller 的实例或类型来自IContext .

如果您将值注入(inject)(构造函数注入(inject)、属性注入(inject))到 StandardKernelCaller 中而不是 resolve ( Get ) 它,那么您将收集类型 StandardKernelCaller来自IContext 。 如果应用属性注入(inject),也许您甚至可以获得 StandardKernelCaller 的实例(但我怀疑它不可用)。

但是,您可以将参数传递给 Get call:命名绑定(bind)的名称(字符串)(解析为使用相同名称注册的绑定(bind),如果没有可用的匹配绑定(bind)则抛出异常)和 IParameter的。 IParameter可以通过 IContext 获取.

关于c# - 是否可以通过 IContext 解析 Ninject 工厂方法中的调用者实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48291530/

相关文章:

c# - 如何为泛型提供默认类型?

c# - GeckoWebBrowser访问一个错误的URL,总是弹出消息框

c# - 使用函数中的表达式编译 LinQ 查询

c# - 如何将 Ninject 命名绑定(bind)与 DependencyResolver 和 PropertyInjection 一起使用

c# - 自托管 Web API 时使用 Ninject InRequestScope()

asp.net-mvc - 全局访问 Ninject 内核

c# - 没有 GC 的无限方法参数

c# - 我该如何组织这段代码?

c# - VS 2015 复制以输出项目引用的 GAC 引用,而不考虑复制本地设置

.net - 将非托管 DLL 部署到输出目录