本文介绍了使用ninject注入到Model类或非控制器类的依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在mvc 3(Steven sanderson Scaffolder)中的Repository模式中使用Ninject 3。

,在ninject中,我有NinjectWebCommon类,在RegisterServices方法中,我解决了依赖关系,我认为我准备去了

  private static void RegisterServices(IKernel kernel)
{
kernel.Bind< ICityRepository>()。到< CityRepository>();
kernel.Bind< IVillageRepository>()。到< VillageRepository>();
}

我在使用构造函数注入的控制器中使用我的存储库,一切都很好。

  public class CityController:Controller 
{
private readonly ICityRepository cityRepository;

//如果您使用依赖注入,可以删除以下构造函数
// public CityController():this(new CityRepository())
// {
//}

public CityController(ICityRepository cityRepository)
{
this.cityRepository = cityRepository;
}

// .........
}

但是当我在其他类(如Model(Entity))类中使用属​​性注入或字段注入时,依赖性不会解决,并且在属性或字段上得到空引用异常。

  [MetadataType(typeof(CityMetadata))] 
public partial class City:IValidatableObject
{
[注入]
public IVillageRepository VillageRepo {get;组; }

public IEnumerable&ValidationResult>验证(ValidationContext validationContext)
{
var village = VillageRepo.Find(5); //将在VillageRepo上抛出空引用异常
}
}

public partial class CityMetadata
{
[ScaffoldColumn(false)]
public int ID {get;组; }

[必需(ErrorMessage = MetadataErrorMessages.Required)]
[StringLength(50,ErrorMessage = MetadataErrorMessages.ExceedMaxLength)]
public string Name {get;组; }
}

我不知道为什么会发生这种情况。那么问题是什么,我如何在非控制器类中使用存储库?

提前感谢。

解决方案

你的问题是,你在期待魔法。您为您的存储库注入一个实现,然后您期望由该存储库创建的数据对象注入创建存储库的引用。



首先,这不行。存储库的实现将在您的实体上调用new()(或Activator.CreateInstance),而不是从Ninject Kernel或Factory请求一个实例。您可以重写存储库(如果您在使用EF时会变得更加棘手),但这可能不值得麻烦。



实体不应该依赖于存储库,甚至不是他们的界面。



编辑:现在我明白为什么你想在你的模型中看到一个回购。我推荐的是一个静态工厂。

  public class工厂
{
public static readonly Instance =新工厂();
[Inject]
public Func< IVillageRepository> VillageRepo {get; set;}
}

然后调用 Kernel.Inject(Factory .Instance); 从你的Ninject初始化代码(你绑定了IVillageRepository)。然后将您的可验证实现修改为工厂.Instance.VillageRepo()。Find(...);


I using Ninject 3 in Repository pattern in mvc 3 (steven sanderson Scaffolder).
and in ninject i have the class "NinjectWebCommon" which in the "RegisterServices" method i resolved the dependencies and i think im ready to go.

  private static void RegisterServices(IKernel kernel)
  {
     kernel.Bind<ICityRepository>().To<CityRepository>();
     kernel.Bind<IVillageRepository >().To<VillageRepository>();
  }

i using my repositories in controllers using constructor injection and everything is fine.

public class CityController : Controller
{
   private readonly ICityRepository cityRepository;

   // If you are using Dependency Injection, you can delete the following constructor
   //public CityController() : this(new CityRepository())
   //{
   //}

   public CityController(ICityRepository cityRepository)
   {
      this.cityRepository = cityRepository;
   }

  // .........
}

but when i use this repositories in other classes like Model(Entity) classes using property injection or field injection the dependency doesn't resolved and i get null reference exception on my Property or field.

[MetadataType(typeof(CityMetadata))]
public partial class City : IValidatableObject
{
   [Inject]
   public IVillageRepository VillageRepo { get; set; }

   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
   {
      var village = VillageRepo.Find(5); // will throw null reference exception on "VillageRepo"
   }
}

public partial class CityMetadata
{
   [ScaffoldColumn(false)]
   public int ID { get; set; }

   [Required(ErrorMessage = MetadataErrorMessages.Required)]
   [StringLength(50, ErrorMessage = MetadataErrorMessages.ExceedMaxLength)]
   public string Name { get; set; }
}

i don't know why this happening. so whats the problem and how can i use the repositories in non-controller classes?
thanks in advance.

解决方案

Your problem is, you're expecting magic. You inject an implementation for your repository, and then you expect that data objects created by that repository are injected with references of the creating repository.

First of all, that doesn't work like that. The implementation of the repository will call new() (or Activator.CreateInstance) on your entities, not ask for an instance from a Ninject Kernel or Factory. You could rewrite the repository (it'll get trickier if you're using EF there...) but it's probably not worth the hassle.

On the top of it all, you shouldn't be needing that at all. Entities shouldn't depend on repositories, imho not even their interfaces.

EDIT: now I see why you want to see a repo in your model. What I recommend is a static factory maybe.

public class Factories
{
public static readonly Instance = new Factories();
[Inject]
public Func<IVillageRepository> VillageRepo  {get; set;}
}

Then call Kernel.Inject(Factories.Instance); from your Ninject initialization code (where you bind IVillageRepository). Then modify your validatable implementation to Factories.Instance.VillageRepo().Find(...);

这篇关于使用ninject注入到Model类或非控制器类的依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 00:36