1

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, ~, 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

Matt0
  • 177
  • 2
  • 9
  • "need access to the web app's paths from the console app" - what does this mean exactly? Which paths, and why? – bzlm Jul 04 '11 at 20:58
  • @bzlm: web app's root path (~), its images directories, the db directories (more than one), temp dirs, various csv repositories, client files, ... The console app pulls data from various backend systems and sticks them in the correct places for the web system to find. To do this neatly, it needs access to the paths used by the web app, else I must hardcode everything, and given how many subsystems are invovled, that will lead to trouble. – Matt0 Jul 04 '11 at 22:00

5 Answers5

1

Write a small web service and expose the desired data from the web app, then just call it from the console app

BlackTigerX
  • 6,006
  • 7
  • 38
  • 48
  • Possibly, but then the web app needs to be running--i cannot just reference it's assemblies. – Matt0 Jul 04 '11 at 18:42
  • @Matt0 - For items like HttpContext.Current, wouldn't the web app need to be running anyway? You can't get the current HttpContext from the assemblies; it is a runtime value. – JeremyDWill Jul 04 '11 at 18:48
  • @JeremyDWill True, so I don't need access to it then. All I want is the path mechanism--you can get them from multiple classes not just HttpContext. But as it happens, all those classes are unavailable. – Matt0 Jul 04 '11 at 18:55
1

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.

Matt0
  • 177
  • 2
  • 9
0

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/

Community
  • 1
  • 1
SpaceBison
  • 3,704
  • 1
  • 30
  • 44
  • Read some of the material and though it would probably work, it seems awefully complicated for such a simple task... And introduces dependencies that we won't use for anything else. – Matt0 Jul 04 '11 at 16:37
  • @Matt0, using mocking to solve this feels like seriously drunken architecture. If the console application relies on stuff that isn't available, then mocking that stuff is pointless, except to get the code to actually run. – bzlm Jul 04 '11 at 20:59
  • @bzlm: agreed I don't see how it will help – Matt0 Jul 04 '11 at 21:25
  • Fair points all round. it was perhaps an ill-considered suggestion of mine. – SpaceBison Jul 06 '11 at 15:47
0

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!

Jan_V
  • 4,244
  • 1
  • 40
  • 64
0

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.

Wyatt Barnett
  • 15,573
  • 3
  • 34
  • 53