Autofac - RouteConfig.cs - asp.net mvc4 - asp.net-mvc

thanks in advance for any help. I changed to mvc4 and start using app_start/routeconfig.cs to register routes.
Probably it dont have any relation with autofac but I cannot find a solution, does anyone know if its neccesary to declare routetable.routes in any additional place - I already declared RouteConfig.RegisterRoutes(RouteTable.Routes); in global.asax - when planning to use autofac with mvc4 razor´s internet template?.
Currently no map.route definition is working in my app. I dont know if I have to declare an instance like
RegisterInstance(RouteTable.Routes);
thank you so much.

This is basically the minimum amount of code to configure Autofac for mvc. You will need to reference Autofac.Integration.Mvc, and if you're using webapi you need to reference Autofac.Integration.Webapi too.
public static class AutofacConfig
{
public static IContainer Register()
{
var assembly = typeof(MvcApplication).Assembly;
var builder = new ContainerBuilder();
builder.RegisterControllers(assembly);
// If you don't need webapi, you can omit this, else you need Autofac.Integration.Webapi
builder.RegisterApiControllers(assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// If you don't need webapi, you can omit this, else you need Autofac.Integration.Webapi
var resolver = new AutofacWebApiDependencyResolver(container);
// Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = resolver;
return container;
}
}
In Global.Asax you can then add
AutofacConfig.Register();
in the Application_Start method as one of the first calls.

Related

CosmosClient Singleton and Global.asax

I'm trying to create a CosmosClient instance for use in an ASP.Net MVC application. Microsoft recommends creating a singleton instance of the client. I've figured out I need something in Application_Start in Global.asax but that's it so far. Can anyone please give me an step by step idiots guide on how to do this as I am new to ASP.Net?
I have the following code running in a console app which creates the instance but I don't know how to translate this to an ASP Web App.
public async Task<bool> setupInitialiseClientAsync() // Use to create and also initialise Cosmos client
{
List<(string, string)> containersToInitialize = new List<(string, string)> { (databaseId, containerId) };
this.cosmosClient = await CosmosClient.CreateAndInitializeAsync(PrimaryConnectionString, containersToInitialize);
this.container = cosmosClient.GetContainer(databaseId, containerId);
return true;
}
Thanks.

MVC SimpleInjector tries to inject in every constructor

I have a MVC project, where i want to register a singleton of a specific service.
When i use simpleinjector, i get an error in all of my other classes with multiple constructors and so on. How do i configure it so ONLY my wanted service is dependency injection and DI is disabled for everything else (like before i used the DI container)?
Example of an exception i get:
No registration for type AccountController could be found and an
implicit registration could not be made. For the container to be able
to create AccountController it should have only one public
constructor: it has 2.
But i don't want AccountController to use dependency injection?!
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
// Create IOC Container
var container = new Container();
// Register services
container.RegisterSingleton<IWebSocketHandler, WebSocketHandler>();
// Verify services
container.Verify();
// Store the container for use by the application
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
}

ASP.Net MVC 5 + SignalR + Ninject

What is the best practice way for to wire up Ninject with both MVC5 and SignalR?
Ninject recommends having Global.asax inherit NinjectHttpApplication and implementing a CreateKernal method:
//Global.asax ([Ninject MVC Website Guidance][1])
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel(new NinjectRegistrations());
var ninjectResolver = new CustomNinjectDependencyResolver(kernel);
DependencyResolver.SetResolver(ninjectResolver); // MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API
return kernel;
}
SignalR would like us to use their OwinStartup class register a NinjectDependencyResolver:
//OWIN Startup ([ASP.Net Website Guidance][2])
public void Configuration(IAppBuilder app)
{
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
var config = new HubConfiguration();
config.Resolver = resolver;
Microsoft.AspNet.SignalR.StockTicker.Startup.ConfigureSignalR(app, config);
}
IKernel and NinjectDependencyResolver are needed in both these locations. One option is to start using Static singletons for these, but this does not seem in the spirit of the loose coupling we are shooting for by using Ninject in the first place.
Thanks for any pointers!
You only need to call MapSignalR from Owin configuration. The Ninject MVC pipeline uses WebActivator to activate Ninject, install package Ninject.MVC5.
Look here how to add SignalR to Ninject startup
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/master/SignalR.EventAggregatorProxy.Demo.MVC4/App_Start/NinjectWebCommon.cs#L45

SignalR 2 Dependency Injection with Ninject

I have an existing MVC application that is using Dependency Injection with Ninject. I installed the Ninject.MVC3 nuget package and it creates a class called NinjectWebCommon in my App_Start, which completely isolates the kernel and registers all of my bindings:
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFoo>().To<Foo>();
}
We have a new requirement that we thought SignalR would be able to satisfy, so we installed SignalR 2 nuget package into the project. I created a Hub and did some searching on how to implement Dependency Injection into the project and found an article that suggests creating a SignalRDependencyResolver. http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection
The article has you creating a kernel in the Startup.cs file that is used for registering SignalR in OWIN:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
kernel.Bind<IStockTicker>()
.To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>() // Bind to StockTicker.
.InSingletonScope(); // Make it a singleton object.
kernel.Bind<IHubConnectionContext>().ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients
).WhenInjectedInto<IStockTicker>();
var config = new HubConfiguration()
{
Resolver = resolver
};
app.MapSignalR(config);
}
}
The problem is that this approach has me creating two different kernels and they seem to have their own set of dependencies that they know how to resolve. If I have a dependency defined in NinjectWebCommon, the Hub doesn't know how to resolve that dependency. Without exposing my kernel in NinjectWebCommon, what is the proper way to add DI into SignalR using the Ninject.MVC3 package?
None of the current answers directly answer your question. Also achieving the result you are after is very straightforward once you know exactly what to do. The "proper" way to do this is to set SignalR's dependency resolver in the CreateKernel method of the NinjectWebCommon class.
Assuming you have created a NinjectSignalRDependencyResolver class as you mention, no other code needs to be added anywhere except for the line highlighted in the code snippet below:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
// THIS LINE DOES IT!!! Set our Ninject-based SignalRDependencyResolver as the SignalR resolver
GlobalHost.DependencyResolver = new NinjectSignalRDependencyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
Apart from the above, nothing more needs to be done except declaring your bindings in the RegisterServices method of NinjectWebCommon. In your example this would look like:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IStockTicker>()
.To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>() // Bind to StockTicker.
.InSingletonScope(); // Make it a singleton object.
kernel.Bind<IHubConnectionContext>().ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients
).WhenInjectedInto<IStockTicker>();
}
Except for the NinjectSignalRDependencyResolver class you created, no other code needs to be added. Importanly, the OwinStartup class remains unmodified, as follows:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
The above example achieves the following important outcomes which were what you asked in your question:
You only have a single Ninject Kernel created
The kernel and all binding configurations remain confined to NinjectWebCommon
The default SignalR resolver is your NinjectSignalRDependencyResolver
Dependency Injection into all SignalR hubs is achieved
Hopefully this helps people out.
Have you tried adding the StockTickerHub itself to your kernel?
By default, SignalR uses Activator.CreateInstance to construct Hubs without any constructor arguments. If you want to inject your own dependencies into a Hub, you can do so by registering the Hub with SignalR's dependency resolver.
https://github.com/SignalR/SignalR/blob/2.0.1/src/Microsoft.AspNet.SignalR.Core/Hubs/DefaultHubActivator.cs#L28
If you want to get really creative, you can register your own IHubActivator instead of registering all of Hubs individually.
I go into more detail in how Hubs are created by default in this answer: SignalR with IoC (Castle Windsor) - which lifetime for hubs?
There is a problem with the singleton scope. I don´t know who should get the blame here (Ninject, SignalR, MVC, etc...), but it works if you use ToConstant:
var binding = Bind<IMustBeSingleton>().ToConstant(new MustBeSingleton());
I had the same problem, and I found the solution: SignalR, WebAPI and MVC sharing the same dependency resolver kernel
I shared a complete solution with MVC, WebAPI and SignalR using the same Ninject kernel: https://drive.google.com/file/d/0B52OsuSSsroNX0I5aWFFb1VrRm8/edit?usp=sharing
That example web app, contains a single page that shows the AppDomain and GetHashCode of an object that is supposed to be unique across the three frameworks, giving a result similar to:
Dependency Test
Framework IMySingletonService instance
MVC AppDomainId:2 / HashCode:5109846
WebAPI AppDomainId:2 / HashCode:5109846
SignalR AppDomainId:2 / HashCode:5109846
I hope this helps.

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