Injecting Session with StructureMap in ASP .Net MVC - asp.net-mvc

I am trying to inject ASP .Net MVC Session into a Controller by providing in interface for it using StructureMap. But StructureMap complaints while trying to do this as HttpContext.Current is not initialized at the time of registry initialization. I am sure there is a way around it I have yet to find. Please point me into the right direction.
Here is my code for more information:
DefaultRegistry.cs:
using System.Web;
using Company.O365Web.Infrastructure;
using StructureMap.Configuration.DSL;
using StructureMap.Graph;
namespace Company.O365Web.DependencyResolution
{
public class DefaultRegistry : Registry
{
#region Constructors and Destructors
public DefaultRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For<ISessionState>()
.Singleton()
.Use(new SessionStateProvider(new HttpSessionStateWrapper(HttpContext.Current.Session)));
}
#endregion
}
}

Related

How do you configure structuremap.MVC 5 in ASP.NET MVC5 to ignore framework interfaces/class instances

The structuremap method, scan.WithDefaultConventions(); in structuremap.MVC 5 assumes the convention IMyClassName , MyClassName for Dependency Injection. This is okay if you have only classes you created.
With ASP.NET MVC 5 application out of the box, the convention IMyClassName , MyClassName does not exits with the User Identity. How do you configure structuremap to ignore ASP.NET Framework interfaces/classes?
StructureMap.MVC5 automatically uses the convention IMyClass and MyClass to DI Resolution. No other configuration is required after adding StructureMap.MVC5 from Nuget. It just works. However ASP.NET Identity does not follow this convention of IMyClass and MyClass.
You will see this exception ""no default instance is registered and cannot be automatically determined for type 'IUserstore" because structure map cannot resolve to require instance
A workaround is request StructureMap.MVC5 to please use default constructor by adding the DefaultContructor attribute of StructureMap as below in the account controller.
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
[DefaultConstructor] //This is the attribute you need to add on the constructor
public AccountController()
{
}
// Other implementations here..........
}
Types can be ignored like so:
public class AuthenticationRegistry : Registry
{
public AuthenticationRegistry()
{
this.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.ExcludeType<IdentityUser>();
});
}
}

Do I need to use ninject.mvc extension anymore?

I see there is an extension for Ninject integration with asp.net-mvc but it looks like I can integrate Ninject with mvc fine without this extension. For example:
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IResolutionRoot _resolutionRoot;
public NinjectDependencyResolver(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}
public object GetService(Type serviceType)
{
return _resolutionRoot.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _resolutionRoot.GetAll(serviceType);
}
}
public class MvcApplication : HttpApplication
{
void Application_Start()
{
var modules = new INinjectModule[] { new ServiceModule() };
var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
Is this some legacy extension or is it still relevant? I see recent updates to the source code so I was a bit confused
You can implement your own Dependency Resolver. So yes you dont need it. You can integrate Ninject quite easily without the extension. But the question is why should you do this? The Ninject.MVC3 extension provides everything to add support for Ninject without having to implement an own Dependency Resolver. This has several advantages:
Unlike the implementation you are proposing, the implementation of this extension is correct and proved to work in many applications.
It is mantained together with Ninject core. In case Ninject core changes all the necessary changes will be done for you. E.g. Ninject 3.0.0 core does not have InRequestScope anymore, but with Ninject.MVC3 you still have this scope.
This extension is much more than a Dependency Resolver. Read the documentation!
It runs side aside with other web technologies and the configuration can be shared. E.g. MVC4 Web API, WCF, WebForms

ASP.NET MVC 2, Ninject 2.2 and no parameterless constructor defined for this object

So I've been spending some time with ASP.NET MVC 2 (currently stuck with using Visual Studio 2008) and have now moved onto using Ninject 2.2 and its MVC integration. I've downloaded Ninject 2.2 and Ninject.Web.Mvc from the following locations:
https://github.com/downloads/ninject/ninject/Ninject-2.2.0.0-release-net-3.5.zip
https://github.com/downloads/ninject/ninject.web.mvc/Ninject.Web.Mvc2-2.2.0.0-release-net-3.5.zip
And referenced them in my MVC 2 project. My Global.asax.cs file looks like this (pretty much what the Ninject.Web.Mvc README says):
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Ninject.Web.Mvc;
using Ninject;
namespace Mvc2 {
public class MvcApplication : NinjectHttpApplication {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected override void OnApplicationStarted() {
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
protected override IKernel CreateKernel() {
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
return kernel;
}
}
}
And a home controller that looks like this:
using System;
using System.Web;
using System.Web.Mvc;
namespace Mvc2.Controllers {
public class HomeController : Controller {
private readonly IFoo foo;
public HomeController(IFoo foo) {
this.foo = foo;
}
public ActionResult Index() {
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
}
}
Now every time I run my project and visit '/' I get a yellow screen of death with a message that says "No parameterless constructor defined for this object." It seems Ninject is not resolving my Foo service and injecting it into HomeController. I imagine I'm missing something really obvious but I'm just not seeing it.
How do I get Ninject to inject Foo into the HomeController, and without using Ninject attributes?
Me: Could you provide a little more information about the IFoo service implementation? Does it have all of its own dependencies satisfied?
Myself: Hmm, no it doesn't. Turns out I didn't bind its dependencies. Boy, is that error message and stack trace misleading!
So my mistake was that I didn't bind one of the dependencies of the IFoo implementation and so Ninject failed silently and tried to continue on its merry way. Which is really unfortunate because it could lead to some really strange behavior once I deviate from a trivial setup. I guess my next question should be how can I get Ninject to fail as early as possible and provide good messaging about what's wrong? But for now I can at least get on with it.

Is there a dependency injection framework for asp net mvc that like spring framework?

bean id="foo" class="com.ems.samples.spring.Foo"
property name="bar" ref="bar"/
/bean
bean id="bar" class="com.ems.samples.spring.Bar"
public class Foo {
private Bar bar;
public String getMessage() {
return "Foo" + bar.getMessage();
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
public class Bar {
public String getMessage() {
return "Bar";
}
}
There's Castle Windsor, Spring.NET, StructureMap, Unity, Ninject and possibly more... check out the MvcContrib project for samples and controller factories that support the mentioned IoC containers.
checkout Munq.DI at munq.codeplex.com. It is a simple, fast DI container with lifetime managers specific to web development. Object can have lifetime duration of Request, Session, Cache, and Container. Additionally, there is a MunqControllerFactory and example for ASP.NET MVC. Full source included.
There's Spring.net for a start, but I've no idea how it plays with asp.net mvc

ASP.NET MVC, MVCContrib, Structuremap, getting it working as the controllerfactory?

I'm trying to get structuremap to correctly create my controllers, I'm using DI to inject an INewsService into a NewsController and thats the only constructor I have.
public class NewsController : Controller
{
private readonly INewsService newsService;
public NewsController(INewsService newsService)
{
this.newsService = newsService;
}
public ActionResult List()
{
var newsArticles = newsService.GetNews();
return View(newsArticles);
}
}
and I'm using this code to start the app
public class Application : HttpApplication
{
protected void Application_Start()
{
RegisterIoC();
RegisterViewEngine(ViewEngines.Engines);
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterIoC()
{
ObjectFactory.Initialize(config => {
config.UseDefaultStructureMapConfigFile = false;
config.AddRegistry<PersistenceRegistry>();
config.AddRegistry<DomainRegistry>();
config.AddRegistry<ControllerRegistry>();
});
DependencyResolver.InitializeWith(new StructureMapDependencyResolver());
ControllerBuilder.Current.SetControllerFactory(typeof(IoCControllerFactory));
}
}
But Structuremap doesn't seem to want to inject the INewsService and I get the error
No parameterless constructor defined for this object.
What have I missed?
I use the "Default Conventions" mechanism that StructureMap provides to avoid needing to individually configure each interface. Below is the code I use to make that work:
My Global.asax has this line in Application_Start (which uses the StructureMap factory from MvcContrib):
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ObjectFactory.Initialize(x =>
{
x.AddRegistry(new RepositoryRegistry());
});
ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory));
}
And the RepositoryRegistry class looks like this:
public class RepositoryRegistry : Registry
{
public RepositoryRegistry()
{
Scan(x =>
{
x.Assembly("MyAssemblyName");
x.With<DefaultConventionScanner>();
});
}
}
The DefaultConventionScanner looks for pairs of Interfaces/Classes that follow the nameing convention of ISomethingOrOther and SomethingOrOther and automatically associates the latter as a concrete type for the former interface.
If you didn't want to use that default convention mechanism, then you would add code in the Registry class to explicity map each of your interfaces to the concrete types with this syntax:
ForRequestedType<ISomethingOrOther>().TheDefaultIsConcreteType<SomethingOrOther>();
Unless I'm missing something, you are not telling StructureMap what concrete type to use for INewsService. You need to add something like:
TheConcreteTypeOf<INewsService>.Is<MyConcreteNewsService>();
I don't know the exact syntax off the top of my head, but that's what you're missing. Once you specify that then it will know what instance of the INewsService to inject into the controller.
ASP.NET MVC currently instantiates controllers using the default parameterless constructor, which precludes any constructor-based dependency injection. To do that, you really need to use the MvcContrib project, which has built-in support for StructureMap (and Castle/Spring.NET/Unity), although the current documentation is non-existent (literally, you get a stub wiki page, not a good sign). Erv Walter's code sample in this thread shows how to set up the StructureMap integration.

Resources