【问题标题】:DI, IoC Bindings with ninject (Binding Interface to IEnumerable<T> method)DI,IoC 与 ninject 绑定(绑定接口到 IEnumerable<T> 方法)
【发布时间】:2024-12-14 07:30:02
【问题描述】:

我有一个界面:

public interface IProductRepository {
    IEnumerable<Product> Products { get; }
}

一种方法:

public IEnumerable<Product> getProducts() { }

我的控制器:

public class ProductController : Controller
{
    private IProductRepository repository;

    public ProductController(IProductRepository productRepository) {
        this.repository = productRepository;
    }

    public ViewResult List() {
        return View(repository.Products);
    }
}

我正在尝试在 AddBindings() 中将它们绑定在一起 {

productDAL db = new productDAL();
IEnumerable<Product> help = db.getProducts();
kernel.Bind<IProductRepository>().To< >;

我试图使用该方法而不是这样的方法:

Mock<IProductRepostiory> mock = new Mock<IProductRespository>();
mock.Setup(m => m.Products).Returns(new List<Product> {
new Product { Name= ... }

kernel.Bind<IProductRepository>().ToConstant(mock.Object);

但是使用 ToMethod 之类的东西。 getProducts() 从数据库返回一个 IEnumerable,然后我希望 ninject 将其注入到 ProductsController,这样我就可以将列表添加到视图中。我知道 Product 类不继承 IProductDepository 也不继承 productDAL,这是故意的。

这是在我的 DependencyResolver 类中。

有人可以帮忙绑定这里吗,我缺少演员表,谢谢。


我想通了,这就是我修复它的方法:

我有一个界面:

public interface IProductRepository {
    IEnumerable<CountyDataset> Products { get; }
}

我有一个 MVC 控制器:

public class ProductController : Controller
{
    private IProductRepository repository;

    public ProductController(IProductRepository productRepository) {
        this.repository = productRepository;
    }

    public ViewResult List() {
        return View(repository.Products);
    }
}

我有一个 DAL:

public class productDAL: databaseDAL {
    public productDAL() {

    }
    public IEnumerable<CountyDataset> Products {
        get { ... }
    }
}

这就是我所缺少的......

现在我有一个产品存储库(和朋友哈哈):

public class lcProducts : IProductRepository {
    private productDAL context = new productDAL();

    public IEnumerable<CountyDataset> Products {
        get { return context.Products; }
    }
}

这是我更正后的 DI 容器:

private void AddBindings() {
        ...
        kernel.Bind<IProductRepository>().To<lcProducts>();
    }

【问题讨论】:

    标签: c# binding ninject


    【解决方案1】:

    你不能——类型不匹配。您必须绑定到IProductRepository 的实例。看起来你的 db 对象实现了接口,所以试试这个:

    kernel.Bind<IProductRepository>().To<productDAL>();
    .
    .
    .
    var db = kernel.Get<IProductRepository>();
    IEnumerable<Product> help = db.getProducts();
    

    请记住,虽然这并不能真正为您带来很多好处。您应该将IProductRepository 作为对其他类的构造函数依赖,以便 DI 真正发挥其魔力。这是您提供的相应使用的类。

    public class ProductController : Controller
    {
        private IProductRepository repository;
    
        public ProductController(IProductRepository productRepository) {
            this.repository = productRepository;
        }
    
        public ViewResult List() {
            return View(repository.Products);
        }
    }
    

    你的依赖解析器现在看起来像这样:

    kernel.Bind<SomeConsumerOfProductRepository>().ToSelf();
    kernel.Bind<Controller>().To<ProductController>();
    .
    .
    .
    var consumer = kernel.Get<Controller>();
    //Use consumer or do whatever you have to do.... 
    

    这将允许 Ninject 自动检测 ProductControllerIProductRepository 的依赖,您已绑定到一个实现,并为您解决它。除此之外,如果需要,您可以轻松地将ProductController 更改为Controller 的新实现。

    【讨论】:

    • 消费者将成为我的 ProductController public class ProductController : Controller { private IProductRepository repository;公共 ProductController(IProductRepository productRepository) { this.repository = productRepository; } public ViewResult List() { return View(repository.Products); } }
    • 如果我这样做: kernel.Bind().To();我收到此严重性代码描述项目文件行抑制状态错误 CS0311 类型“DataLibrary.Dal.productDAL”不能用作泛型类型或方法“IBindingToSyntax.To()”中的类型参数“TImplementation” .没有从“DataLibrary.Dal.productDAL”到“DataLibrary.Interfaces.IProductRepository”的隐式引用转换。 ClerkHelper c:\users\hanka\onedrive\documents\visual studio 2017\Projects\ClerkHelper\ClerkHelper\Slab\NinjectDependencyResolv
    • 那是因为你的productDAL 类没有实现IProductRepository 接口。
    • 我知道我试图做这样的事情: Mock mock = new Mock(); mock.Setup(m => m.Products).Returns(new List { new Product { Name=... } kernel.Bind().ToConstant(mock.Object);
    • 那行得通。很难回答,因为我觉得我在这里错过了很多上下文。