How to use griffin.mvccontrib.localization with Ninject - asp.net-mvc

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.

Related

Where does an MVC Controller get it's database context at run time

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.

What is the best place to configure a MongoDB connection in ASP.NET MVC?

Another MVC framework I've used - Symfony2 - uses a dependency injector to carefully configure and manage dependencies.
Does ASP.NET MVC have anything similar which would let me configure a MongoDB connection and then pass it down to my controller logic where it can be used?
There are many different dependency injection libraries you can use with Asp.net MVC, here's a (non comprehensive) list:
StructureMap
Ninject
Autofac
Unity
Spring.net.
If you go looking for them in Nuget, typically there will be one package for the container itself, and a different package that adds the Asp.Net MVC plugins.
Take a look at them, figure out which flavor you like, then configure your mongo db connection to be per-request, add the connection to your controller constructor, and away you go. If you pick a lib and update your question, I'm sure someone will answer with specific code etc.
This is generally done in the web.config file
<appSettings>
<add key="MONGOHQ_URL" value="mongodb://localhost/YourDBName"/>
</appSettings>
The value can be referenced like this...
public class ConfigEnvironment
{
public static string GetConnectionString()
{
return ConfigurationManager.AppSettings.Get("MONGOHQ_URL") ??
"mongodb://localhost";
}
}
Use this to create your database
MongoDatabase.Create(ConfigEnvironment.GetConnectionString())

structuremap asp .net mvc registration

I'm using structuremap and Asp .Net MVC in a project. Currently I'm registering my dependency resolutions in the MVC layer for everything below it (service, data, etc.). However, I was wondering how I could do this by only registering what's directly below the MVC layer, namely, the Service layer. Basically my controllers have services injected into them and that's all I want my UI layer to know about. Within the service classes I have repositories injected and want those registered with structuremap in there... and so on. In other words, I want each layer to only be dependent (as much as possible) to the layer directly below it.
Thanks!
A good approach is to use structuremap conventions combined with structuremap registries. That will take care of most of your registration issues. Structuremap can scan your bin and map dependencies that it finds in all dll's in your bin.
Look into the Scan method combined with a StructureMap Registry class:
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(y =>
y.FullName.StartsWith("JustLookAtTheseDlls"));
// Use default conventions
x.WithDefaultConventions().OnAddedPluginTypes(y =>
y.HybridHttpOrThreadLocalScoped());
//Are there any registries? If so, register them
x.LookForRegistries();
}
A registry looks something like this, and you can just drop one into each of your projects to register the items in each:
public class IocRegistry :
StructureMap.Configuration.DSL.Registry
{
public IocRegistry()
{
For<IDocumentStore>().Singleton()
.Use<RavenStore>();
}
}
You root application should have the registry that contains the scan statement above. Then initialize structuremap like so:
ObjectFactory.Configure(x => x.AddRegistry(
new MyTopLevelRegistry()));
Where MyTopLevelRegistry looks like this:
public class MyTopLevelRegistry: Registry
{
public MyTopLevelRegistry()
{
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(
y => y.FullName
.StartsWith("InsertYourNamespacePrefix"));
x.WithDefaultConventions().OnAddedPluginTypes(
y => y.HybridHttpOrThreadLocalScoped());
x.LookForRegistries();
});
}
}
Keep in mind if you set it to "WithDefaultConventions" it will automatically map IMyClass to MyClass so you don't even have to specify that stuff in the registries. You just have to register items that don't follow that convention.
Hope this helps!
I recommend the usage of a composition root in a own library.
In the project i am working on we put the StructureMap registry in a library named xx.yy.IoC and we call the configuration code from Global.asax.
The MVC layer has only a link to the IoC library. The IoC Library has the dependencies to the other layers (Domain, Data, etc.)
As a tip: This article has changed our views about layering. jeffrey palermo onion architecture
I'm not sure I understand what you are asking.
You have to register all the objects that will be resolved. Then in your controller you just expect ISomeService passed to constructor. Controller doesn't know that ISomeService has injected IRepositories for example.

Using Ninject with Asp.NET Web API Beta ApiController

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;
}

MVC3, Ninject, MvcSiteMapProvider - How to inject dependency to overridden method

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.

Resources