Background: I have a ASP.NET MVC3 app, with a database. I also have a complex console app, which (amongst other things) initialises the web app's database: generate, add constraints, add sprocs, add triggers, seed, etc. I cannot move the console logic into the web app (doesn't make sense in our architecture).
Problem:
The console app is obviously not running in a hosted environment, so does not have access to HostingEnvironment
, MapPath
, HttpContext.Current
, Server.MapPath
,开发者_如何学Python ~
, etc. But I need access to the web app's paths from the console app. Also, the console app calls into the web app, which then uses these classes normally, but which are of course all null or undefined.
Question: Is there some way to spoof one of these classes so that I can access the hosting environment's path mechanism, even though it's not running?
I can hardcode all the paths I need into the console app, but that is highly undesirable.
I'm under the impression that this should be possible, because the same need would be required for unit testing.
TIA
Write a small web service and expose the desired data from the web app, then just call it from the console app
What I've done (though I don't really like it):
Instead of scattering various paths around the web app, we have a single static Paths
class, which contains private static readonly
strings for every major resource path in the system (paths that T4MVC doesn't help us with). Whenever I need a path to anything, I ask that class, and it performs the necessary Path.Combine()
etc. on the strings within -- so the result is that all hardcoded strings are present in one clean and easy to maintain class.
So I added a property public static string ApplicationRootPath { get; }
to that class (note the public, and lack of readonly), and a static constructor which initialises it to ApplicationRootPath = HostingEnvironment.MapPath("~");
or "/"
depending on your use case.
Then, from the console app, I can override that "root" directory by Paths.ApplicationRootPath = "some absolute or relative path here";
. After that single line, I can then access all the paths in the web app, which work.
Actually it's quite neat, but still not ideal. I'll accept this as the answer unless someone has a better idea.
Moq is great for mocking the MVC3 contexts that you require. It's fairly easy to setup and you can override the methods and properties that would usually run under a web context to return the objects you desire.
Rather than attempting to explain further, start here:
How do I mock the HttpContext in ASP.NET MVC using Moq?
MVC 3 Unit Test - Get Actual Response Data
http://www.sharpedgesoftware.com/Blog/2011/03/14/mocking-a-controllercontext-with-authenticated-user-with-moq-for-aspnet-mvc-3
http://code.google.com/p/moq/
You could try out a StructureMap (or some other IoC framework) for this to work.
In a project I'm currently working on we've wired the HttpContextBase
to the HttpContext.Current
object in a website.
This way we can use the HttpContext
features within any environment.
For our unit-tests we're using some stub/mock object which overrice from the HttpContextBase
. Most of the objects you want to use got an interface or base class you can use to set up the wiring.
For mocking the .NET Framework you could try out Pex & Moles. It should be able to do such, or so I'm told. Haven't used that myself, but it looks pretty neat!
Got a few of these floating around. In most cases you really just need 1 or 2 configuration values then you can calculate your paths pretty effectively. Value #1 is the root of the web application -- from there you can easily build out a url to any resource. Value #2 is the physical location of the web app if that in fact matters in this context.
精彩评论