我想这是我想要实现的一个非常简单的场景。
我只是想知道是否可以在 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/