I'm stuck. I was using the method outlined here for wcf web api p6 Ninject working with WCF Web API Preview 5, however things are quite a bit different with the mvc implementation in the beta. There is a good article here http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver that talks about building your own custom dependency resolver, however i would like to use the same implementation i'm using for my mvc view controllers...e.g. Ninject. I've tried a few things based on the IoC Unity example in the article too, but nothing has panned out yet. Any help pointing me in the right direction would be much appreciated. I'm going to keep digging on my own as well. Thanks in advance!
Here's where I'm at. I was using WebActivator to bootstrap the code but I've since dropped it to the Application_Start() just to take one more thing out of the equation.
protected void Application_Start()
{
var kernel = new StandardKernel(new MyNinjectModule());
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
And am receiving the following error:
The type Ninject.Web.Mvc.NinjectDependencyResolver does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator.Parameter name: commonServiceLocator
Found the solution
Perhaps there is/will be a more elegant way but this is now working for me. I'm also adding my custom message handler here as well.
[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart.ApiBootstrapper), "Start")]
namespace MyApp.AppStart
{
public class ApiBootstrapper
{
public static void Start()
{
var kernel = new StandardKernel(new MyNinjectModule());
var resolver = new NinjectDependencyResolver(kernel);
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(resolver.GetService, resolver.GetServices);
GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiAuthHandler());
}
}
}
I never used the WebAPI but since the semantic of the IDependencyResolver is exactly the same as the one from MVC3 you should be able to use the same implementation: https://github.com/ninject/ninject.web.mvc/blob/master/mvc3/src/Ninject.Web.Mvc/NinjectDependencyResolver.cs
Update:
The Ninject.Web.WebAPi extension adds support for ApiControllers
I found the answer and updated my question above with the solution. The solution itself was more or less present in the Using the Web API Dependency Resolver article, i just had to keep tweaking for ninject. Both answers helped me quickly narrow this down so thanks to #Remo and #James.
May sound silly but have you made sure you have a reference to the CommonServiceLocator / CommonServiceLocator.NinjectAdapter nuget package or associated assemblies. Your NinjectDependencyResolver may not be able to resolve the reference to IServiceLocator.
The same code will work for both MVC and the WebApi, however because the WebApi was inspired by MVC and the MVC assemblies do not have to be referenced in order to use WebApi (or vise versa), there is a fair amount of duplication of code between the two frameworks. If you want to use MVC you're dependencies will come from System.Web.Mvc, if you want to use WebApi you'll use System.Web.Http. If you want to use both you'll have to differentiate in your code which to use when, using a more explicit namespace resolution.
In your case your problem is that MVC came first and the NinjectDependancyResolver class inherits from System.Web.Mvc.IDependencyResolver. You'll want to create an exact duplicate of the NinjectDependancyResolver class and instead inherit from System.Web.Http.IDependencyResolver instead. Use THIS class to setup your IoC and you'll be good to go.
I found a nice solution here.
It's pretty easy if you're already using the Ninject CommonServiceLocator / Bootstrapper:
private static IKernel CreateKernel() {
var kernel = new StandardKernel();
RegisterServices(kernel);
GlobalConfiguration.Configuration.ServiceResolver
.SetResolver(new NinjectServiceLocator(kernel));
return kernel;
}
Related
I am trying to get into the new ASP.NET MVC 6 stuff, but I'm having a very hard time with their new DI system. I have tried to find resources online, but everything I find covers only the absolute most bare minimum to use it.
I was previously using Ninject, and I have several wire-ups that work like this:
Bind<IDocumentStore>()
.ToMethod(c => CreateDocumentStore())
.InSingletonScope();
private static IDocumentStore CreateDocumentStore() {
// lots of initialization code, etc.
return documentStore;
}
But so far I am having a difficult time finding out how to translate this kind of behaviour to Microsoft's new DI system. All I can find are examples like this:
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
and:
services.AddMvc();
Where everything seems to work entirely on the default constructor for the target service. Is there any way to produce the behaviour I am needing in this new DI system?
I've seen the
services.Configure<TOptions>(options => {});
But I'm not really clear on whether that will do what I am thinking, or if it is reserved for specific behaviours.
The AddTransient method has various overloads, one of which accepts a lambda expression:
services.AddTransient<IDocumentStore>(s => CreateDocumentStore());
However it seems you are using the Ninject InSingletonScope() modifier so this may be more appropriate:
services.AddSingleton<IEmailSender>(s => CreateDocumentStore());
Additional note: There is some pre-release documentation available (of course, it's not complete and may be incorrect but may help)
Also you could continue use Ninject by adding Microsoft.Framework.DependencyInjection.Ninject to your project and then configure it with following code:
public IServiceProvider ConfigureServices(Microsoft.Framework.DependencyInjection.IServiceCollection services)
{
var kernel = CreateMyKernel();
kernel.Populate(services); // Wire up configured services and Ninject kernel with Microsoft tool
return kernel.Get<IServiceProvider>();
}
I am creating one demo application to learn how to use repository pattern for performing Insert operation.I am using Nop Commerce**(http://www.nopcommerce.com) **code for repository pattern
Error:No parameterless constructor defined for this object
I have seen this link:MVC: No parameterless constructor defined for this object
This is my Structure:
My Repository interface:
public partial interface IRepository<T>
{
void Insert(T entity);
}
My Service Layer:
public partial interface IEmployeeService
{
void InsertCategory(EmployeeMaster employeeMaster);
}
My Class which will implement that interface(service):
public partial class EmployeeService : IEmployeeService
{
#region Fields
private readonly IRepository<EmployeeMaster> _employeeMasterRepository;
#endregion
#region Ctor
public EmployeeService
(
IRepository<EmployeeMaster> employeeMasterRepository
)
{
this._employeeMasterRepository = employeeMasterRepository;
}
#endregion
public virtual void InsertCategory(EmployeeMaster employeeMaster)
{
if (employeeMaster == null)
throw new ArgumentNullException("employeeMaster");
_employeeMasterRepository.Insert(employeeMaster);
}
This is my controller:
public class HomeController : Controller
{
#region Fields
private readonly IEmployeeService _employeeService;
#endregion
#region Constructors
public HomeController
(
IEmployeeService employeeService
)
{
this._employeeService = employeeService;
}
#endregion
Getting Error:No parameterless constructor defined for this object
I have studied regarding this error and all the sources are saying that use Dependency injection to solve this error.
Can anybody guide me how to use dependency injection to solve this error??
Maybe you're taking as a sample a project that is too complex for you at this moment. Nopcommerce is a big and full featured product that has a lot of elements, so it easy to get lost. Not the best sample to learn how the repository pattern works, but I certainly recommend you to check it again once you have the basic concepts clear to see them used in a real scenario.
NopCommerce uses Autofac for dependency injection, a very popular IoC container. You can look for a class called DependencyRegistrar in the project Nop.Web.Framework to see how it is used, if you're curious about it. You can get more examples on how to use dependency injection with Autofac in their repository and their getting started guide.
My recommendation is to look for an easier to follow example. For starters, any of the popular IoC containers will be OK until you have your own criteria to choose one. For instance you can follow the Autofac's guide for MVC
You're correct - you'll need to use something like Unity, Ninject or Autofac to get this running.
Essentially - the steps are roughly the same regardless of the tech used.
Using unity as an example:
1) In your MVC project, use NuGet to add "Unity Bootstrapper for MVC". (right click references, manage nuget packages, search for unity online, select "Unity Bootstrapper for MVC"
This will add a few things to your project - the most interesting is the unityConfig.cs in App_start.
2) In unityConfig.cs - find RegisterTypes method
RegisterTypes is where you tell the unity container "when you need one of X, use implementation Y" - in your case "when you need an IEmployeeService, use EmployeeService"
3) In register types - add your type mappings - for example, in your case:
container.RegisterType<IEmployeeService, EmployeeService>();
AND
4) Bit more complicated: as you have IRepository and you need this to resolve your employeeService correctly you'll also have to register a generic type against a generic implementation (it's a little odd). Looking at your types, it's going to be something like:
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
(You'll need to resolve the namespaces according to your projects).
So - what this is saying is...
Right MVC - when you need an IEmployeeService use employeeService, and
when you need an IRepository<>, use Repository<>
Now - because of the webActivator that was added during the NuGet installation (right next door to UnityConfig.cs), that should be it - the webActivator sets the DependencyResolver.Current to something that uses this unityContainer.
Beacause of this, MVC will now use this new unityContainer whenever it tries to instantiate your controllers, resolving the type mappings on the way.
The webActivator and unityConfig classes do alot of the heavy-lifting for you, just elaborate registerTypes and you should at least have a foot-hold in the solution.
HTH - good luck.
PS - DI itself is a massive subject - far too much for here, you'll bump into all sort of weird and wonderful things (supplying Ctor args for resolutions, lifetime management just for a start!) - it's fun, but not trivial, so you'll have to excuse me if this doesn't work "out of the box" (it's almost impractical to think it would) - this is merely just a vague attempt to give you a foothold in the subject!
For more info on unity - I suggest you read up here (Dev guide to using Unity on MSDN)
Given this code:
namespace Eisk.Controllers
{
public class EmployeesController : Controller
{
DatabaseContext _dbContext;
public EmployeesController(DatabaseContext databaseContext)
{
_dbContext = databaseContext;
}
public ViewResult Index()
{
var employees = _dbContext.EmployeeRepository;
return View(employees.ToArray());
}
Note that the constructor doesn't new up a database.
When accessed from a unit test I can inject a databaseContext and the controller will use that for the duration of the test. What I can't figure out is where this code is getting the database context it's using at run time. If I could find that out I might be able to figure out how to circumvent that behavior and have it use a mocked/in memory DB instead.
More explanation:
I don't have access to a legacy database for this application right now so I'm trying to Mock up an in memory data source that gets filled from xml files. That's why I need to be able to circumvent the default database context creation.
More Information:
Thanks for all the help so far you wonderful people you.
Steven seems to have directed me down the correct path.
In the Global.asax file is this call:
DependencyInjectorInitializer.Init();
Following that through the code I get to:
public static void Initialize()
{
_container = new UnityContainerFactory().CreateConfiguredContainer();
var serviceLocator = new UnityServiceLocator(_container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
DependencyResolver.SetResolver(new UnityDependencyResolver(_container));
}
At least that gets me headed in the right direction. Now I have to figure out how Unity is going about creating the context so I can do my intervention.
Let me plug the EISK MVC Employee Info Starter Kit here. It's a well thought out system developed by Mohammad Ashraful Alam Et al. that includes a well fledged example of how many of the new technologies fit together. MVC 5, Entity Framework 6, Unity, Authentication, OpenAuth, DI, Moq, and a couple of other things. Can be used as a template, general learning, or training.
Employee Info Starter Kit
With the default configuration of ASP.NET MVC, a controller should have a default constructor (i.e. a public constructor with no parameters). If not ASP.NET MVC will throw the following exception:
Type 'Eisk.Controllers.EmployeesController' does not have a default
constructor
If this however works, this means that you (or another developer) overwrote the default configuration by either using a custom IControllerFactory or custom IDependencyResolver. Most developers do this by using an open source Dependency Injection library (such as Simple Injector, Autofac or Castle Windsor). If you pull in the NuGet MVC integration packages for such library, it will usually do this configuration for you. So somebody on your team might have done this for you.
My advice is: talk to your team and ask them how they did this and which container they used and where you can find the configuration for that.
I'm trying to use MVC Contrib Localization in my Asp.net MVC application, for now I have it working with resource files, but I want to use it with Sql Server,
I'm checking this tutorial: http://www.codeproject.com/Articles/352583/Localization-in-ASP-NET-MVC-with-Griffin-MvcContri
but it uses Autofac as the IoC container which I don't understand, does anyone have used it with Ninject? or anyone knows how this Autofac code can be transated to Ninject:
// Loads strings from repositories.
builder.RegisterType<RepositoryStringProvider>().AsImplementedInterfaces().InstancePerLifetimeScope();
builder.RegisterType<ViewLocalizer>().AsImplementedInterfaces().InstancePerLifetimeScope();
// Connection factory used by the SQL providers.
builder.RegisterInstance(new AdoNetConnectionFactory("DemoDb")).AsSelf();
builder.RegisterType<LocalizationDbContext>().AsImplementedInterfaces().InstancePerLifetimeScope();
// and the repositories
builder.RegisterType<SqlLocalizedTypesRepository>().AsImplementedInterfaces().InstancePerLifetimeScope();
builder.RegisterType<SqlLocalizedViewsRepository>().AsImplementedInterfaces().InstancePerLifetimeScope();
Thanks in advance.
I am trying to do the same thing at the moment with the Ninject.Web.MVC NuGet package.
I am not sure if Ninject has anything similar to .AsImplementedInterfaces() however you can still bind the interfaces yourself if not, its just more manual work looking at Griffin.MvcContrib's classes and what interfaces they implement.
One example to put in the NinjectWebCommon RegisterServices method is:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ILocalizedStringProvider>()
.To<RepositoryStringProvider>().InRequestScope();
...
}
The InRequestScope extension (https://github.com/ninject/Ninject.Web.Common/wiki/Inrequestscope), from what I have read so far, is the closest I can see to the AutoFac .InstancePerLifetimeScope() http://code.google.com/p/autofac/wiki/InstanceScope
As for .RegisterInstance(new AdoNetConnectionFactory("DemoDb")).AsSelf();
There is a .ToSelf() method for Ninject but I am not entirely sure what this line is doing yet myself.
I have an MVC3 application that is using Ninject and MvcSiteMapProvider.
I have created this class which MvcSiteMapProvider uses to dynamically add nodes to my sitemap:
public class PageNodeProvider : DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// need to get repository instance
var repository = // how do I get this???
foreach (var item in repository.GetItems())
{
yield return MakeDynamicNode(item);
}
}
}
The MvcSiteMapProvider instantiates this type itself, so I'm not sure how to inject my repository into it.
I thought about using service location by getting a handle on my kernel and calling Get<Repository>() in the method. But, I saw this property when looking at the definition of NinjectHttpApplication:
// Summary:
// Gets the kernel.
[Obsolete("Do not use Ninject as Service Locator")]
public IKernel Kernel { get; }
Do not use Ninject as Service Locator ?! How else am I supposed to do this?
I then found this question here on stackoverflow and all answers say don't use Service Location.
What am I supposed to do?
This seems to be another chapter from the book "Why providers are bad design?". You have the same problem as with any kind of ASP.NET providers. There are no really good and satisfying solutions for them. Just hacks.
I think the best option you have is to fork the project and change the DefaultSiteMapProvider to use DepencencyResolver instead of the Activator and provide the implementation back to the community. Then you can use constructor injection in your PageNodeProvider implementation. This will solve the problem once for all types and everyone.
Of course you could also use the DependencyResolver just in your implementation. But this is by far not the best solution because you should get the instances as close to the root as possible, it makes testing more complicated and it solves the problem just for you.
Even though I see that you've decided to ditch the provider altogether, I'd like to elaborate on using the DependencyResolver. Basically, you can manually get the correct repository instance via Ninject using
var repository = DependencyResolver.Current.GetService<IRepository>();
This is less robust, as you have to maintain this as well as the NinjectMVC3.cs class should the stuff change, and it is a bit more complicated to test.