Dot*_*mer 37 asp.net asp.net-mvc dependency-injection ninject repository-pattern
我已经设置了我的项目Ninject IoC.
我的项目有常规Asp.Net MVC控制器和Web Api控制器.现在,Ninject使用Web Api但Ninject不适用于常规Asp.MVC控制器.
我的常规MVC控制器实现;
public class GalleryController : BaseController
{
public GalleryController(IUow uow)
{
Uow = uow;
}
........
}
Run Code Online (Sandbox Code Playgroud)
与常规控制器一起使用时出错
An error occurred when trying to create a controller of type 'Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
Run Code Online (Sandbox Code Playgroud)
但是,当我使用Web Api尝试相同的代码时,它可以工作
public class GalleryController : BaseApiController
{
public GalleryController(IUow uow)
{
Uow = uow;
}
......
}
Run Code Online (Sandbox Code Playgroud)
我的界面包含不同的存储库(工厂模式)
public interface IUow
{
// Save pending changes to the data store.
void Commit();
//Repositoryries
IRepository<Gallery> Gallery { get; }
IMenuRepository Menus { get; }
}
Run Code Online (Sandbox Code Playgroud)
NinjectDependencyScope 类;
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
var disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
Run Code Online (Sandbox Code Playgroud)
NinjectDependencyResolver 类;
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
Run Code Online (Sandbox Code Playgroud)
Ninject Global.asax的配置;
public class IocConfig
{
public static void RegisterIoc(HttpConfiguration config)
{
var kernel = new StandardKernel(); // Ninject IoC
//kernel.Load(Assembly.GetExecutingAssembly()); //only required for asp.net mvc (not for webapi)
// These registrations are "per instance request".
// See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/
kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
.InSingletonScope();
kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
kernel.Bind<IUow>().To<Uow>();
// Tell WebApi how to use our Ninject IoC
config.DependencyResolver = new NinjectDependencyResolver(kernel);
}
}
Run Code Online (Sandbox Code Playgroud)
Global.asax中
protected void Application_Start()
{
// Tell WebApi to use our custom Ioc (Ninject)
IocConfig.RegisterIoc(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
AreaRegistration.RegisterAllAreas();
}
Run Code Online (Sandbox Code Playgroud)
Ody*_*Ody 33
我已经写了一些要点来帮助配置Ninject与MVC和Web Api.只需包含文件:
要为具体类型添加Bindings,只需将它们放在Load()MainModule 的方法中即可.您可以根据需要创建任意数量的模块,以保持绑定的有序性.但是你还必须将它们添加到Modules属性中返回的数组中.
Then Add to the Application_Start() method
NinjectContainer.RegisterModules(NinjectModules.Modules) (for MVC)NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules) (for WebApi)Note that you can use the same NinjectModules.Modules for both the MVC and WebApi registration. I just separated it for clearity
UPDATE: Remember to Remove NinjectWebCommon.cs from your project as it loads and bootstraps a new kernel at Runtime which unfortunately is only for MVC.
UPDATE: You can also use
NinjectContainer.RegisterAssembly() (for MVC)NinjectHttpContainer.RegisterAssembly() (for WebApi)This will scan your current assembly for all modules. This way you can put your modules anywhere in your project and it will be registered
Dig*_*Dan 15
使用MVC 5和Web API 2.2,我通过确保包含以下NuGet包解决了这个问题:
Ninject.MVC5Ninject.Web.WebApi.WebHost 用于Web API这安装了其他Ninject依赖项并允许我RegisterServices通过NinjectWebCommon.cs.
Dot*_*mer 12
在搜索了很多之后,事实证明我们不能将Ninject与web api和常规mvc一起使用.我的意思是,我们必须单独配置存储库.
然后我找到了一篇很好的文章,解释了如何将Ninject与asp.net mvc和web api一起使用:http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc4-and-的WebAPI美
现在,我没有得到错误,它正在工作:D
更新1:
还尝试使用.NET Framework 4.5在MVC 4 Web API中编写依赖注入的简单实现
小智 6
这是一个适合我的简单解决方案:

在包管理器控制台中逐个执行:
安装包Ninject
安装包Ninject.MVC5
将NinjectDependencyResolver.cs添加到IoC文件夹:
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Dependencies;
namespace DemoApp.IoC
{
public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
public void Dispose() { } //it is not necessary to implement any dispose logic here
}
}
Run Code Online (Sandbox Code Playgroud)在App_Start/NinjectWebCommon.cs中进行以下更改:
在CreateKernel方法中添加以下行:
NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel); DependencyResolver.SetResolver(ninjectResolver); // MVC GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API
在RegisterServices方法中添加绑定,如:
kernel.Bind <IHelloService>().To <HelloService>();
现在NinjectWebCommon.cs看起来像:
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DemoApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(DemoApp.App_Start.NinjectWebCommon), "Stop")]
namespace DemoApp.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using DemoApp.IoC;
using System.Web.Mvc;
using System.Web.Http;
using DemoApp.Config;
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 Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel);
DependencyResolver.SetResolver(ninjectResolver); //MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; //Web API
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHelloService>().To<HelloService>();
}
}
}
Run Code Online (Sandbox Code Playgroud)
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DemoApp.Config;
namespace DemoApp.Controllers
{
public class HomeController : Controller
{
private IHelloService helloService;
public HomeController(IHelloService helloService)
{
this.helloService = helloService;
}
// GET: /Home/
public string Index()
{
return "home/index: " + helloService.GetMessage();
}
}
}
Run Code Online (Sandbox Code Playgroud)
UserController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using DemoApp.Config;
namespace DemoApp.Controllers
{
public class UserController : ApiController
{
private IHelloService helloService;
public UserController(IHelloService helloService)
{
this.helloService = helloService;
}
[HttpGet]
public string Data()
{
return "api/user/data: " + helloService.GetMessage();
}
}
}
Run Code Online (Sandbox Code Playgroud)
IHelloService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
public interface IHelloService
{
string GetMessage();
}
}
Run Code Online (Sandbox Code Playgroud)
HelloService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
public class HelloService : IHelloService
{
public string GetMessage()
{
return "Hi";
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在在浏览器中进行一些测试.对我来说是:
就是这样.
| 归档时间: |
|
| 查看次数: |
47265 次 |
| 最近记录: |