使用ninject,我知道我可以绑定到某个实现,这样当我这样做时:
ISomeCache myCache = Ninject.Get<ISomeCache>();
Run Code Online (Sandbox Code Playgroud)
它将加载我绑定ninject的具体实现.
假设我在数据库(Web应用程序)中存储了我想要使用的具体实现,当我在管理面板中更改它时,它应该使用我想要的类.
这可能吗?
我是MVC和依赖注入的新手.请帮助我理解它应该如何工作.我用Ninject.这是我的代码:
在Global.asax文件中:
private void RegisterDependencyResolver()
{
var kernel = new StandardKernel();
kernel.Bind<IDbAccessLayer>().To<DAL>();
// DAL - is a Data Access Layer that comes from separated class library
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
protected void Application_Start()
{
RegisterDependencyResolver();
}
Run Code Online (Sandbox Code Playgroud)
IDbAccessLayer实现非常简单:
public interface IDbAccessLayer
{
DataContext Data { get; }
IEnumerable<User> GetUsers();
}
Run Code Online (Sandbox Code Playgroud)
现在在Controller中我需要创建一个获取IDbAccessLayer参数的构造函数.这才有效.
现在我不知道如何将连接字符串传递给DAL.如果我尝试用接受参数的东西替换DAL的构造函数,它就不起作用.使用消息引发异常没有为此对象定义无参数构造函数
我正在阅读Apress ASP.NET MVC 3书,并试图确保我为一切可能创建单元测试但是在花了一天的时间试图找出为什么编辑不会保存(参见这个问题)我想要为此创建一个单元测试.
我已经知道我需要为以下类创建一个单元测试:
public class EFProductRepository : IProductRepository {
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products {
get { return context.Products; }
}
public void SaveProduct(Product product) {
if (product.ProductID == 0) {
context.Products.Add(product);
}
context.SaveChanges();
}
public void DeleteProduct(Product product) {
context.Products.Remove(product);
context.SaveChanges();
}
}
public class EFDbContext : DbContext {
public DbSet<Product> Products { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Ninject.MVC3和Moq并且之前已经创建了几个单元测试(虽然正在处理前面提到过的书),所以我慢慢地了解它.我已经(希望正确地)创建了一个构造函数方法,使我能够传入_context:
public class EFProductRepository : IProductRepository {
private EFDbContext _context; …Run Code Online (Sandbox Code Playgroud) 在kernel.Bind上获取和出错(scanner = 2010 ..."扫描仪"在VS 2010中有一个小错误行.
无法将lambda表达式转换为'System.Type []'类型,因为它不是委托类型
像2.0中的旧kernel.scan一样自动注册.我无法弄清楚我做错了什么.添加和删除了这么多Ninject包.完全迷失了,浪费时间.
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
//using Ninject.Extensions.Conventions;
using Ninject.Web.WebApi;
using Ninject.Web.Mvc;
using CommonServiceLocator.NinjectAdapter;
using System.Reflection;
using System.IO;
using LR.Repository;
using LR.Repository.Interfaces;
using LR.Service.Interfaces;
using System.Web.Http;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void …Run Code Online (Sandbox Code Playgroud) 我一直在使用Ninject:
ninjectKernel.<IBlogRepository>().To<BlogRepository>();
Run Code Online (Sandbox Code Playgroud)
我希望返回一个特定的obejct.我该如何得到这样的东西呢
ninjectKernel.<IInvestorRepository>(). // returns this : new BlogRepository(new (new BlogContext(Settings.Default.BlogConnection)))
Run Code Online (Sandbox Code Playgroud) 我正在尝试第一次实现测试驱动的开发.我的项目是dotnet 3.5中的ac#.我已阅读在C#书中专业测试驱动开发,现在我想测试我的项目包含Windows service.I've读到最好的做法是,所有代码必须在test.The以下是我的窗口服务实现方法onStart和onStop
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using log4net;
namespace MyUcmaService
{
public partial class MyUcmaService : ServiceBase
{
private Worker _workerObject;
private static MyUcmaService aMyUcmaService;
private Thread _workerThread;
private static ILog _log = LogManager.GetLogger(typeof(MyUcmaService));
public MyUcmaService()
{
InitializeComponent();
aMyUcmaService = this;
}
protected override void OnStart(string[] args)
{
// TODO: inserire qui il codice necessario per avviare il servizio.
//Debugger.Launch();
AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
try
{
_workerObject = new Worker(); …Run Code Online (Sandbox Code Playgroud) 默认的MVC模板使用“ @ DateTime.Now.Year”来显示版权年份,但是我宁愿到处都使用NodaTime。
我目前正在使用Ninject将IClock的实例注入到执行时间或日期特定内容的Controller中。是否有建议的方式来访问MVC中类似于“ DateTime.Now”的“全局IClock”?我想我可以将IClock注入到每个Controller中,然后将其传递到每个视图中,但是有时可以访问全局对象会很不错。
我知道我可以在Layout模板中使用SystemClock.Instance ...而是引用一个全局的,可测试的IClock会更好。
我不知道这是可能的,但我想有一个可以使用实体框架也使用Ninject来填充在运行时的具体实现接口来加载和保存的一类.
我开始使用这样的构造函数:
public FancyObject(ICatProvider kitty)
{
this.kitty = kitty;
}
Run Code Online (Sandbox Code Playgroud)
这就像Ninject一样,我们得到了一个Cat - 它可以使用Entity Framework将实体保存到SQLServer.但是,它在尝试加载实体时失败,因为实体框架需要无参数构造函数.
所以我尝试将它放在这样的属性上:
[Inject]
public ICatProvider kitty { get; set; }
public FancyObject()
{
}
Run Code Online (Sandbox Code Playgroud)
这可以从DB加载,但Kitty始终为null.
我在绑定中的所有内容是:
kernel.Bind<ICatProvider>().To<FancyFileBasedCat>();
Run Code Online (Sandbox Code Playgroud)
我猜这是因为我正在使用实体框架来创建实体,所以Ninject没有看到.
我错过了一些明显的东西吗?有一个很好的方法来做到这一点?
我通过Package Manager控制台安装了NuGet包Ninject Integration for WebApi2.
根据项目的GitHub页面上的wiki,这应该创建一个NinjectWebCommon在App_Start文件夹中调用的类.但事实并非如此.
同样的GitHub wiki页面解释了你应该看到的内容,以便你自己添加它.所以我尝试NinjectWebCommon自己创建课程.这里的问题是我找不到OnePerRequestModule以下代码段中的命名空间.
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
Run Code Online (Sandbox Code Playgroud)
替代方案,并根据GitHub维基页面两者之间没有有效区别,就是修改global.asax.所以我尝试了这种方法并添加了一些像这样的绑定
private void RegisterServices(IKernel kernel)
{
kernel.Bind<IEntityAccess>().To<EntityAccess>();
kernel.Bind<IDictionaryRepository>().To<DictionaryRepository>();
}
Run Code Online (Sandbox Code Playgroud)
并发现我的项目构建,但是当一个请求被发送到WebAPI项目时,它找不到(即,我收到404响应).
所以显然还有其他一些必要的布线,而不是我的项目.
看来,尽管改变了我的global.asax来源NinjectHttpApplication,但global.asax不再被称为.
谁能告诉我我可能会失踪的是什么?我已经卸载并重新安装了几次NuGet包,但NinjectWebCommon该类从未出现过,我的global.asax文件也没有被修改过.
我还阅读了Ninject自己的文档,但令人沮丧的是这是一个相当大的教程,涵盖了IoC的基础知识以及Ninject如何运行而不是告诉你如何开始使用Ninject.
还有这篇SO帖子询问如何开始使用Ninject for WebAPI,所以看起来他们的NuGet包有些不对劲.
我需要在完全注入特定类型(通过命名约定)时绑定ICommand到特定实现,然后我还需要一个具有构造函数参数的类型的多重绑定- 并且需要接收相同的实例,因为我需要我的命令InSingletonScope.IEnumerable<ICommand>
我试过这个,其中包括:
// note: ICommandMenuItem naming convention for [Foo]Command: [Foo]CommandMenuItem
var item = types.SingleOrDefault(type => type.Name == commandName + "CommandMenuItem");
if (item != null)
{
_kernel.Bind<ICommand>().To(command)
.WhenInjectedExactlyInto(item)
.InSingletonScope()
.DefinesNamedScope("commands");
_kernel.Bind<ICommand>().To(command)
.WhenInjectedExactlyInto<ConfigurationLoader>()
.InNamedScope("commands");
}
Run Code Online (Sandbox Code Playgroud)
但每次我进入构造函数时ConfigurationLoader,IEnumerable<ICommand>参数都不包含任何元素.无论是否有命名范围,我认为我需要告诉Ninject"看起来我有两个相同类型的绑定,我希望你给我两个相同的实例".
第一个绑定工作 - 我知道因为我的菜单项在点击时会做一些事情.但是ICommand注入(不是?!)的方式有问题ConfigurationLoader,我不知道如何修复它.
ninject ×10
c# ×5
asp.net-mvc ×3
asp.net ×2
moq ×1
ninject-2 ×1
nodatime ×1
nuget ×1
nunit ×1
structuremap ×1
tdd ×1
unit-testing ×1