What is the purpose of IApplicationBuilder.New() - asp.net-mvc

In the new ASP.NET 5.0 (vNext), the startup code relies on the IApplicationBuilder interface. The Use method is used to add a handler to the builder, while Build is used to construct the final delegate. But I can't figure out what is the purpose of New. I've been digging in GitHub, but can't find any place where that's used.
Anyone understand what is the purpose of that method?

New() creates a second ApplicationBuilder, sharing all the ApplicationServices and ServerFeatures of the first one, but none of the middleware. It is used internally by the branching extensions (Map, MapWhen, UseWhen) to create the new 'branch'.
You can find the implementation here: ApplicationBuilder.cs.
In some cases, it is also useful in higher-level frameworks.
For exemple, the [MiddlewareFilter] attribute in MVC Core uses New() internally to execute a piece of ASP.NET Core middleware inside the MVC framework (i.e. as a filter). MVC Core creates a small pipeline around the middleware, builds it into a RequestDelegate, then runs the HttpContext through it. Just like ASP.NET Core does with your 'main' pipeline built in Startup.cs.
Thanks to this feature, we can reuse a piece of general-purpose ASP.NET Core middleware, from inside MVC.
For more information, see MiddlewareFilterBuilder.cs in ASP.NET MVC Core.

It appears to be there to branch [clone] the original instance (as can be demonstrated in src/Microsoft.AspNet.Http/Extensions/MapExtensions.cs). There was also a previous MapWhenExtensions.cs, but it appears to have been removed from the dev branch.)
I suspect it's an artifact of a previous design that would provide the ability to bind middleware based on circumstances without affecting the root's configuration. The fact that it's been there since before IBuilder was refactored to IApplicationBuilder and that most dependencies were in files that have since been removed from the dev branch, I would venture a guess that it's old news.
Of course it's hard to tell given neither the interface nor the base implementation are commented.

Related

Accessing NInject kernel from a dependent assembly

I have an ASP.NET MVC 5 project where I need to use a custom web-service based e-mail service (long story! Can't change it, though).
I wrapped up the e-mail web service into a separate assembly and packaged all the dependencies in there.
In my ASP.NET MVC 5 app, I'm using Ninject for dependency injection, and it works really well inside the MVC project - the controllers get their dependencies injected "magically" , and it's a joy to use.
But now: for my e-mail sending component, I'd like to write a "mock" or simulator for use locally when doing development. So basically, I would need to be able to bind the IMailService to both the MailService (real implementation), as well as the MailServiceSimulator (my dummy implementation). Ninject supports that, no problem:
Bind<IMailService>().To<MailService>().Named("Production");
Bind<IMailService>().To<MailServiceSimulator>().Named("Simulator");
BUT: the problem is this: I register all the dependencies with Ninject in the MVC application (in the NinjectWebCommon class in App_Startup) - but I'd like to be able to have a factory class in my "mail service" project that can be told to return a real implementation - or the simulator - for the mail sending component. But how can I get access to the Ninject kernel in order to get the desired service?
Somehow, I'd need to be able to do either
return kernel.Get<IMailService>("Production");
if the real implementation is desired, or
return kernel.Get<IMailService>("Simulator");
if the development-time simulator for the IMailService should be used.
Since my MVC app already uses the "MailService" assembly as a reference, I cannot really make the "MailService" use the "MVC" project as a reference.... so how can I access the Ninject kernel (that gets created inside the "MVC" assembly at startup) from within a referenced "MailService" assembly?? Seems I'm going in circles, one assembly requiring the other and then the other requiring the first one again as a dependency.....
Any ideas?
Accessing the Kernel, or doing DI business, in your MailService project seems like a leaky abstraction.
Assuming the "Production/Simulator" switch is located in the appSettings as a "MailSwitch" setting, you may leave out the named bindings and go for :
Bind<IMailService>().To<MailService>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Production");
Bind<IMailService>().To<MailServiceSimulator>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Simulator");

How to inject 3rd party IOC container into ASP.NET Core Startup class

I'm creating a web API using ASP.NET Core, and I'm using SimpleInjector as my DI framework. I understand the basics of how to use SI with ASP.NET Core; my problem is more an architectural one.
I have a project with integration tests for the API project, in order to test the raw API endpoints and responses. Naturally, the test server (set up using Microsoft.AspNetCore.TestHost) should use the API project's real Startup class.
The problem lies in where to register mocks for the controllers' dependencies, because I don't want to have all the production implementations being registered when testing: Firstly, most of them are, of course, dependencies used by the production implementations of the controller dependencies I'll be mocking in the first place; and secondly, in case I update my controllers and forget to register mocks of the new dependencies, I want my code to fail (container verification) instead of silently using production dependencies that are present in the container.
Thus, the dependencies can't be registered in the Startup class. That's fine by me – I think I'd rather keep the composition root in a separate assembly referencing all other assemblies, anyway. AFAICS the ASP.NET Core project would need to reference this project, which exposes a single method that returns a pre-registered container that can be used in the Startup class, where it's needed to register e.g. the controller activator (and will undergo final validation).
But this begs the question: How to get the container – being already registered with all my application components (whether production implementations from the composition root project, or mocks from the integration test project) – into my Startup class?
My initial solution is to simply have a static property on the Startup class called e.g. Container, and assign that before using WebHostBuilder. This seems "pragmatically robust": The application will fail fast (NullReferenceException) if it's not set before the Startup class is run, and the property is only used during setup, so I don't really need to guard against it being set multiple times or being set to null or any such thing – if it's assigned before startup, it works, if not, it won't start.
Does this seem like a solid solution, or am I oblivious to any obvious ways this will will come back to bite me later on? Are there any better solutions?

MVC Web Api - barebones minimal project structure

I'm looking at this MVC WebApi starter kit (for Angular/TypeScript)
Ignoring all the client side code, I noticed the author has made a WebApi that is extremely bare bones. Has has taken out most scaffolding including _ViewStart.cshtml, _Layout.cshtml, and forgoed the convention of controllers in Controllers folder and views in View folder under subdirectory with same name of controller, etc.
He added some interesting Routing and Validation classes that I havent seen before in a Core folder and put controllers in Api folder and Views directly into Views folder with an Index.cshtml at the root.
It's very clean and barebone project structure for a standalone web api that will do nothing except serve data to a client heavy application. I kind of like it this way but before jumping ship I'm wondering what drawbacks this approach has and if I'm actually giving up any core features of the framework by doing it this way. For example, clearly MVC Areas are being given up here in favor of flexibility to create your own view folders structure and seperation of application sections (I'm okay with getting rid of MVC Areas I rarely used them anyways). Another thing is I don't think a Controller action method can return View() and it will find it in the Views folder by convention of the controller name. I'm also okay with that since I will only be serving JSON data and will use 100% client side templating.
Are there any other core features that are being abandoned that I'm missing that may make me regret going with this project structure?
When I create Web APIs that are hosted in IIS, the only files in my web application are web.config, global.asax and global.asax.cs. Everything else is not required.
Take a look at this template if you haven't already before you decide how to structure your ASP.Net MVC / Angular project:
http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83
You can always add components into your project later, so I wouldn't seat it too much. I like to start with a lean/mostly empty project first and add things myself so that I fully understand what I'm adding.

How to (not) specify scope in class libraries with Ninject3

I've an ASP.NET MVC application using Ninject3 (NuGet install). The solution contains:
an MVC project (composition root);
a Domain Model project;
a Data Layer project;
a scheduler project (running scheduled jobs within a windows service and holding an alternative composition root);
some other projects.
I'm following the approach to have many small modules spread across the projects defining the bindings. The two composition roots use exactly the same bindings.
I cannot figure out how to configure scope for the modules within the class libraries. For example, given these bindings:
Bind<IDomainService1>()
.To<Service1Impl>()
.InSingletonScope(); //This should always be a singleton
Bind<IDomainService2>()
.To<Service2Impl>(); //No scope specified
I would always want a single instance of Service1Impl, whereas scope for Service2Impl should depend on the composition root used. MVC project should have InRequestScope() for Service2Impl (and for all other bindings with unspecified scope). Scheduler project, which does not run within an http context, should use InThreadScope().
Is this approach correct? If yes, what is the right way of configuring this behaviour?
In Ninject, not specifying the scope means InTransientScope().
Your choices are to either duplicate the bindings or create a custom InScope() scoping rule for the binding.
The cleanest solution (especially given that MVC is already in play) is for you to create a plugin that slots into the InRequestScope() mechanism.
There is a CreateScope() method which currently has minimal documentation in the ninject.extensions.namedscope README, which is used like this. It requires you to select 'Include Prerelease' in NuGet. (And I should be writing a wiki article on it but I have too many other things on my plate...)

ASP.NET MVC application with plugin and multitenancy support with separate AppDomains?

Problem
I have an ASP.NET MVC 3 application with the plug-in/module architecture and multi-tenancy support. MEF is used to resolve dependencies and load pluggable parts.
Each module consists of controllers, views, and other objects (phisically it's one assembly). Modules are loaded into tenants.
The simple configuration might look like this:
Tenant 1:
Module A, version 1.0 (ModuleA.dll)
Module B, version 1.0 (ModuleB.dll)
Tenant 2:
Module B, version 1.0 (ModuleB.dll)
Dll's for different modules and different versions are stored separately in different physical locations.
And application is running on one AppDomain (default one).
However, if we would like to do configuration where different tenants use different module versions, we encounter problem with loading the same assembly in different version. Which means that scenario below is not fully working because during resolving types from ModuleB we got composition mismatch exception (version 1.0 and 1.5 was loaded into MEF but only one assembly has been loaded into AppDomain by assembly loader).
Tenant 1:
Module A, version 1.0 (ModuleA.dll)
Module B, version 1.0 (ModuleB.dll)
Tenant 2:
Module A, version 1.5 (ModuleB.dll)
Solution?
So we came up with one solution, which is to load different tenants and theirs modules/assemblies into separate AppDomains. Meaning that from our example Tenant1 and Tenant2 are loaded into AppDomain1 and AppDomain2. In ASP.NET MVC pipeline we hooked up into controller factory in order to choose proper app domain, which would look like this:
Request is handled by default AppDomain (the one that web application started)
Controller factory
Takes Tenant_Id from the request and resolves proper controller from proper AppDomain (we have Tenant_Id->Tenant->AppDomain relation)
Returns ControllerProxy (which is a proxy class that implements IController and inherits MarshalByRefObject to be able to pass controller between different App Domians)
Action Invoker
Proper action is invoked on controller proxy object and right now execution takes place in underlying app domian
And here we bumped into problem because action invoker is not able to pass not serializable RequestContext to another app domain (in other words controllerProxy.Execute(RequestContext context) is throwing exception about serialization)
Question(s):
How to pass RequestContext (non serializable object) between app domains in a nice way?
Is it possible to hook up into another step in the pipeline to redirect execution to underlying app domain (before controller factory?)
Or any ideas about another solution for this problem?
Not possible. ASP.NET will come back and haunt you if you try to use different AppDomains.
Instead, use the role based authorization to control access for the different modules.
I've just written an article about plugin systems in ASP.NET MVC3: http://blog.gauffin.org/2012/05/griffin-mvccontrib-the-plugin-system/
This doesn't directly answer your question about multiple app domains within ASP.NET MVC. However, regarding other options, you might want to check out the Managed Application Framework (a.k.a. System.Addin). It is part of the .NET Framework, and is similar to MEF in that it supports dynamically loading modules. However, it has built in functionality for splitting those modules across app domains. It might be better suited to your needs. I'm not sure how well it fits with ASP.NET MVC, though.
This document on MSDN should get your started with MAF.

Resources