所以我开始使用Ninject进行依赖注入,我想知道人们将内核用作工作单元类型对象(如Linq2Sql Datacontexts)的对象工厂的想法.我会像普通的依赖项一样注入它们,但这会引入一些我想避免的对象生存期问题.DataContexts与一般依赖项不同,因为您应该根据需要启动新实例并在完成后处理它们.
要做这样的事情,我只需设置一个这样的提供者......
class SomeDataContextProvider : Provider<SomeDataContext>
{
private static string _connectionString = "someConnectionString"
protected override SomeDataContext CreateInstance(IContext context)
{
return new SomeDataContext(_connectionString);
}
}
Run Code Online (Sandbox Code Playgroud)
将它们绑定在一个模块中......
class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<SomeDataContext>().ToProvider(SomeDataContextProvider);
}
}
Run Code Online (Sandbox Code Playgroud)
并在需要时使用标准内核......
class MyClassThatNeedsADataContext
{
private StandardKernel _kernel = new StandardKernel(new MyModule());
public void SomeMethod()
{
using (var db = _kernel.Get<SomeDataContext>())
{
//Use the context
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于什么本质上是一个静态工厂来说似乎有点沉重,但无论如何我正在使用Ninject进行其他工作.我喜欢它为团队中的成员提供了一个工厂惯例,而不是让他们躲避它(在奇怪的地方创建一堆不同的工厂类,或者只是在对象上放置静态方法等).
思考?有没有更好的方法来处理使用依赖注入的DataContexts或WCF服务客户端等工作单元依赖项?
我有一个自定义成员资格,它使用我的CustomerService首先使用EF代码与数据库进行通信(4.1)我使用ninject将CustomerService注入我的自定义成员资格类.但是当我尝试验证时,我得到一个上下文处理错误.这是因为在我的上下文中,存储库和服务是InRequestScope().因为我使用[inject]在我的自定义成员资格的属性上注入CustomerService,而在ninject中使用_kernel.Inject(Membership.Provider),它只在启动时注入了一个.
我读了很多关于这个问题的帖子,但找不到解决这个问题的答案.
有人有解决方案吗?
什么是使用Ninject与MVC 3,最好的方式如何?
它正在使用控制器工厂?还是使用NinjectHttpApplication?
如何获得MVC 3的ninject?我环顾四周,但我似乎无法弄清楚如何获得所需的..mvc.dll
任何例子都会对我和其他人有所帮助.
谢谢!
我有一个控制器
[MyAttribute]
public class MyController: Controller
{
public MyController(InterfaceA a, InterfaceB b)
{
}
}
Run Code Online (Sandbox Code Playgroud)
如果请求来自具有MyAttribute的控制器,我希望InterfaceA始终绑定到ClassA.所以我打了个电话.
Bind<InterfaceA>.To<ClassA>().WhenClassHas<MyAttribute>();
Run Code Online (Sandbox Code Playgroud)
InterfaceB的一个实例化,ClassB,有一个像这样的构造函数.
public ClassB(InterfaceC c)
Run Code Online (Sandbox Code Playgroud)
我希望InterfaceC在被调用的控制器具有MyAttribute时绑定到C类.但是,我以前的绑定不起作用,因为父类是中间类,而不是控制器本身.反正有没有写绑定所以如果调用控制器具有属性,它将在任何地方工作?
编辑:我的解决方案使用雷莫的建议
public static IBindingInNamedWithOrOnSyntax<TBinding> WhenControllerHasAttribute<TBinding>(this IBindingWhenSyntax<TBinding> instance, Type type)
{
Func<IRequest, bool> hasAttribute = (request) =>
{
while (request.ParentRequest.Target != null)
{
request = request.ParentRequest;
}
return request.Target.Member.ReflectedType.IsDefined(type, false);
};
return instance.When(hasAttribute);
}
Run Code Online (Sandbox Code Playgroud) 我看到Ninject与asp.net-mvc 集成有一个扩展,但看起来我可以将Ninject与mvc完美集成而没有这个扩展.例如:
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IResolutionRoot _resolutionRoot;
public NinjectDependencyResolver(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}
public object GetService(Type serviceType)
{
return _resolutionRoot.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _resolutionRoot.GetAll(serviceType);
}
}
public class MvcApplication : HttpApplication
{
void Application_Start()
{
var modules = new INinjectModule[] { new ServiceModule() };
var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
Run Code Online (Sandbox Code Playgroud)
这是一些遗留扩展还是仍然相关?我看到源代码的最新更新,所以我有点困惑
我有这个ViewModel
public class CustomerSuscribeViewModel : IValidatableObject
{
[DataMember(IsRequired = true)]
[DataType(DataType.Text)]
public string Name { get; set; }
public string SurName { get; set; }
[DataMember(IsRequired = true)]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataMember(IsRequired = true)]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
[DataMember(IsRequired = true)]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Inject]
public IDataUsers DataUsers { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(DataUsers.Get(new UserFilter() {Email = Email}).Any())
{
yield return new …Run Code Online (Sandbox Code Playgroud) 以这个例子为例:
Bind(typeof(IRepository<>)).To(typeof(Repository<>));
Run Code Online (Sandbox Code Playgroud)
这对 NInject 有效,我的问题是这是否是滥用/反模式。
这样做的问题是您不能拥有 IRepository<> 类型的成员/参数变量,因此拥有此绑定实例的唯一方法是通过带有类型请求的工厂。IE
_kernel.Get(typeof(IRepository<>));
Run Code Online (Sandbox Code Playgroud)
一种可能的探索途径可能是使用动力学;
public Foo(IRepository<dynamic> repository)
{}
Run Code Online (Sandbox Code Playgroud)
至少在这里我们有一个构造函数参数被注入,它遵循控制反转。
我问上述问题是因为我问过关于开放泛型的另一个问题;在这种情况下,以下...
public Foo(IEnumerable<IRepository<dynamic>> allRepoInstancesInjected)
Run Code Online (Sandbox Code Playgroud)
......似乎应该是可能的。
c# generics dependency-injection ninject inversion-of-control
我开始在我的项目中使用Ninject来自动绑定抽象类的所有子类.对此的绑定是 - 简单易行 - 如下:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses().
.InheritedFrom<AbstractGenerator>()
.BindBase());
Run Code Online (Sandbox Code Playgroud)
但是,我发现这不起作用.经过一些实验,我发现这不起作用的原因是我的所有实现(和抽象类)都标记为内部.
我可以想象这是一些安全功能,以防止绑定从内部泄漏到外部.但我可以为这些类添加显式绑定.因此,我的问题是:有人知道这是否是预期的行为?有没有办法解决这个问题,除了让我的所有课程都公开?
我有三个通用接口
public interface IRepositorioBase<T> where T : class { }
public interface IServiceBase<T> where T : class {}
public interface IAppBase<T> where T : class {}
Run Code Online (Sandbox Code Playgroud)
我有三个相应的具体泛型类实现
public class RepositorioBase<T> where T : class { }
public class ServiceBase<T> where T : class {}
public class AppBase<T> where T : class {}
Run Code Online (Sandbox Code Playgroud)
而另一个类是使用类泛型创建的,例如
public class ExpenseCardRepository : RepositoryBase<ExpenseCard>, IExpenseCardRepository{ }
public class ExpenseCardService : ServiceBase<ExpenseCard>, IExpenseCardService
{
private readonly IExpenseCardRepository _repository;
public ExpenseCardService(IExpenseCardRepository repository) : base(repository)
{
_repository = repository; …Run Code Online (Sandbox Code Playgroud) 我收到错误消息“没有为此对象定义无参数构造函数”。在MVC 5应用程序中。

控制器是:
public class HomeController : Controller
{
private IUserService userService;
public HomeController(IUserService userService)
{
this.userService = userService;
}
[HttpGet]
public ActionResult Index()
{
var user = userService.GetUser();
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
Ninject WebCOmmon CS类是:
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(QuestionWave.Web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(QuestionWave.Web.App_Start.NinjectWebCommon), "Stop")]
namespace QuestionWave.Web.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using QuestionWave.Data;
using QuestionWave.Service;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary> …Run Code Online (Sandbox Code Playgroud)