定义 Ninject 的无作用域绑定以保持代码干燥
Defining Ninject's binding without scope to keep the code DRY
我的解决方案中有一个 Web 项目和一个 Windows Service 项目。我为这 2 个项目创建了 2 个不同的绑定模块,但是正如您所看到的,它有很多重复代码...唯一的区别是我使用 InRequestScope()
作为 Web 项目和 InTransientScope()
用于 Windows 服务 项目。
是否可以合并绑定,并根据 project/entry 点添加范围?
public class WebModule : NinjectModule
{
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Bind<IMyRepository>().To<MyRepository>().InRequestScope();
// more types ... InRequetScope();
}
}
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().InTransientScope();
Bind<IMyRepository>().To<MyRepository>().InTransientScope();
// more types ... InTransientScope();
}
}
更新:
正如ninject team所解释的那样,我们可以在两种情况下使用InRequestScope()
...因为在Windows服务项目中没有请求的概念,ninject将使用默认范围,即服务项目中的 InTransientScope()
。
原答案
我想到的最佳解决方案是创建一个扩展方法:
public static class NinjectExtensions
{
public static IBindingNamedWithOrOnSyntax<T> GetScopeByName<T>(this IBindingInSyntax<T> syntax, string scope)
{
if (scope.Equals("request", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InRequestScope();
}
else if (scope.Equals("thread", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InThreadScope();
}
else if (scope.Equals("singleton", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InSingletonScope();
}
return syntax.InTransientScope();
}
}
并动态设置范围。
public class MyModule : NinjectModule
{
private string _scope = "transient";
public MyModule()
{
if (Convert.ToBoolean(ConfigurationManager.AppSettings["IsWebProject"]))
{
_scope = "request";
}
}
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().GetScopeByName(_scope);
Bind<IMyRepository>().To<MyRepository>().GetScopeByName(_scope);
// more types ... InRequetScope();
}
}
注意:我不确定是否有更好的解决方案...这只是我想到的最干净的方法。
我的解决方案中有一个 Web 项目和一个 Windows Service 项目。我为这 2 个项目创建了 2 个不同的绑定模块,但是正如您所看到的,它有很多重复代码...唯一的区别是我使用 InRequestScope()
作为 Web 项目和 InTransientScope()
用于 Windows 服务 项目。
是否可以合并绑定,并根据 project/entry 点添加范围?
public class WebModule : NinjectModule
{
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Bind<IMyRepository>().To<MyRepository>().InRequestScope();
// more types ... InRequetScope();
}
}
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().InTransientScope();
Bind<IMyRepository>().To<MyRepository>().InTransientScope();
// more types ... InTransientScope();
}
}
更新:
正如ninject team所解释的那样,我们可以在两种情况下使用InRequestScope()
...因为在Windows服务项目中没有请求的概念,ninject将使用默认范围,即服务项目中的 InTransientScope()
。
原答案
我想到的最佳解决方案是创建一个扩展方法:
public static class NinjectExtensions
{
public static IBindingNamedWithOrOnSyntax<T> GetScopeByName<T>(this IBindingInSyntax<T> syntax, string scope)
{
if (scope.Equals("request", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InRequestScope();
}
else if (scope.Equals("thread", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InThreadScope();
}
else if (scope.Equals("singleton", StringComparison.InvariantCultureIgnoreCase))
{
return syntax.InSingletonScope();
}
return syntax.InTransientScope();
}
}
并动态设置范围。
public class MyModule : NinjectModule
{
private string _scope = "transient";
public MyModule()
{
if (Convert.ToBoolean(ConfigurationManager.AppSettings["IsWebProject"]))
{
_scope = "request";
}
}
public override void Load()
{
Bind<ApplicationDbContext>().ToSelf().GetScopeByName(_scope);
Bind<IMyRepository>().To<MyRepository>().GetScopeByName(_scope);
// more types ... InRequetScope();
}
}
注意:我不确定是否有更好的解决方案...这只是我想到的最干净的方法。