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
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.
Related
I think this should be fairly simple but I can't find anything on google on this for some reason
I have a WebAPi 2.0 controller (type:ApiController) that can read the read the request headers
Request.Headers.GetValues("SomeHeader");
In the same project I have another class (AccessFactory) that I would like to access the headers from.
Reason being that I would not want to do the same code for every function call to read all the needed headers at the point where they are actually needed.
Within a separate project / DLL you can still get access to the current HTTP context (and thus the request headers) using the System.Web.HttpContext.Current object.
As an aside, I would add that if this DLL is meant to be re-usable across different applications, then consider whether it will be used on non-web applications, and if so you should avoid making dependencies on a web-based context like this. Instead you might consider passing in the header values you need as simple types, or in a custom object. That way they can indicate the context, but a non-web app could pass in equivalent contextual values of its own. But that's a separate design decision depending on the exact purpose and how you intend to use this DLL library in future.
So we have a very large ASP.NET WebForms applications (Recently updated to .NET 4.0), and I want to attempt to put MVC in alongside it.
I've read lots of articles around the fact that the 2 types of applications do sit well beside each other. However, the current site makes heavy use of Spring.NET.
Ideally, all I want to do is start adding MVC pages to it, utilising the existing configuration of the business logic.
I've tried just using the MvcContextHandler, however, this leads to errors (The virtual path '/currentcontext.dummy' maps to another application, which is not allowed.) so I'm thinking that it's not as easy as that.
The reason I want to utilise the existing objects is that these will contain context information about the user, and what they've previously selected in the flow, so utilising the existing class that have been instantiated would be very useful.
So does anyone know if this is possible, and if so, are there any resources around to show how to do it?
I'm currently thinking that chaining IoC containers might be an option, so resolving controllers using Ninject, so the parameters are mapped to get the dependencies from the Spring container, but that seems like a long way around...
We upgraded a medium LOB-app to MVC3/Spring.Net and retained the analytics part written in Asp.Net WebForms (Telerik controls, reporting services), so it is possible.
Imho I did not use the MVC3 support facilities brought with Spring.Net and instead wrote a new one. At that time MVC3 was quite new the documentation that ultimately helped was:
http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html
According to Brad, to implement a dependency resolver for MVC, you will need to implement this interface:
public interface IDependencyResolver {
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
http://msdn.microsoft.com/en-us/library/system.web.mvc.idependencyresolver.aspx
I'm not a hater of singletons, but I know they get abused and for that reason I want to learn to avoid using them when not needed.
I'm developing an application to be cross platform (Windows XP/Vista/7, Windows Mobile 6.x, Windows CE5, Windows CE6). As part of the process I am re-factoring out code into separate projects, to reduce code duplication, and hence a chance to fix the mistakes of the inital system.
One such part of the application that is being made separate is quite simple, its a profile manager. This project is responsible for storing Profiles. It has a Profile class that contains some configuration data that is used by all parts of the application. It has a ProfileManager class which contains Profiles. The ProfileManager will read/save Profiles as separate XML files on the harddrive, and allow the application to retrieve and set the "active" Profile. Simple.
On the first internal build, the GUI was the anti-pattern SmartGUI. It was a WinForms implementation without MVC/MVP done because we wanted it working sooner rather than being well engineered. This lead to ProfileManager being a singleton. This was so from anywhere in the application, the GUI could access the active Profile.
This meant I could just go ProfileManager.Instance.ActiveProfile to retrieve the configuration for different parts of the system as needed. Each GUI could also make changes to the profile, so each GUI had a save button, so they all had access to ProfileManager.Instance.SaveActiveProfile() method as well.
I see nothing wrong in using the singleton here, and because I see nothing wrong in it yet know singletons aren't ideal. Is there a better way this should be handled? Should an instance of ProfileManager be passed into every Controller/Presenter? When the ProfileManager is created, should other core components be made and register to events when profiles are changed. The example is quite simple, and probably a common feature in many systems so think this is a great place to learn how to avoid singletons.
P.s. I'm having to build the application against Compact Framework 3.5, which does limit alot of the normal .Net Framework classes which can be used.
One of the reasons singletons are maligned is that they often act as a container for global, shared, and sometimes mutable, state. Singletons are a great abstraction when your application really does need access to global, shared state: your mobile app that needs to access the microphone or audio playback needs to coordinate this, as there's only one set of speakers, for instance.
In the case of your application, you have a single, "active" profile, that different parts of the application need to be able to modify. I think you need to decide whether or not the user's profile truly fits into this abstraction. Given that the manifestation of a profile is a single XML file on disk, I think it's fine to have as a singleton.
I do think you should either use dependency injection or a factory pattern to get a hold of a profile manager, though. You only need to write a unit test for a class that requires the use of a profile to understand the need for this; you want to be able to pass in a programatically created profile at runtime, otherwise your code will have a tightly coupled dependency to some XML file on disk somewhere.
One thing to consider is to have an interface for your ProfileManager, and pass an instance of that to the constructor of each view (or anything) that uses it. This way, you can easily have a singleton, or an instance per thread / user / etc, or have an implementation that goes to a database / web service / etc.
Another option would be to have all the things that use the ProfileManager call a factory instead of accessing it directly. Then that factory could return an instance, again it could be a singleton or not (go to database or file or web service, etc, etc) and most of your code doesn't need to know.
Doesn't answer your direct question, but it does make the impact of a change in the future close to zero.
"Singletons" are really only bad if they're essentially used to replace "global" variables. In this case, and if that's what it's being used for, it's not necessarily Singleton anyway.
In the case you describe, it's fine, and in fact ideal so that your application can be sure that the Profile Manager is available to everyone that needs it, and that no other part of the application can instantiate an extra one that will conflict with the existing one. This reduces ugly extra parameters/fields everywhere too, where you're attempting to pass around the one instance, and then maintaining extra unnecessary references to it. As long as it's forced into one and only one instantiation, I see nothing wrong with it.
Singleton was designed to avoid multiple instantiations and single point of "entry". If that's what you want, then that's the way to go. Just make sure it's well documented.
I've got application A which runs application B as a console app. I'd like to write unit tests as part of application A which validate the input to/output from application B, but application B uses hard coded paths to look for some of its inputs. I'd like to be able to run the application, but intercept the call to read from c:\wherever\whatever.txt and provide the contents of that file myself.
Any frameworks or pieces which can do this for me?
This requires patching the Win32 CreateFile API function. Which is merely technically possible with Detours from Microsoft Research. Which requires unmanaged C or C++.
Tackle this problem at the source, having hard-coded path names in source code is unreasonable.
This is almost impossible!! I say almost because it is possible to intercept calls in the CLR but it is black magic and not recommended unless you are a CLR developer - perhaps a few hundred people in the world.
You can make the hard-coded paths as command line parameters and solve your problem this way.
You could include application B as a reference in application A, and then use Mocking frameworks to change the behaviour of B's methods or properties when calling it's API directly. This is the same process used for unit tests when setting up expectations on dependencies. There are limitations that generally this only works if the object in question is an interface, or contains vi
rtual (overridable) methods/properties. The solution may also be dependent on being able inject a dependency into Bs API, which may or may not be possible depending on the scenario.
Moq, Rhino Mocks. and TypeMock all provide this functionality. Here's a quick example of Moq to override the behaviour of a GetPath method with an alternative value:
// create a mocked version of a class and setup an expectation
var appBClassMoq = new Mock<AppBClass>();
appBClassMoq.SetUp(o => o.GetPath()).Returns("C:\MyNewPath");
// get the mocked instance
var appBClass = appBClassMoq.Object;
// run some code, when it hits GetPath() it will return the mock value
appBClass.SomeMethodThatCallsGetPath();
I have two projects, the DLL project which has all my logic and data access stuff, and the ASP.NET project which does my forms etc.
I am a bit confused. I thought if I added the System.Web namespace reference to the DLL project I would be able to reference the Session state information of the ASP.NET page.
I could use each page to get the session info out and pass it to the DLL for the processing but would love to be able to process things directly from the DLL class(s).
Is this possible?
I have fiddled with the System.Web namespace and just seem able to get a reference to the Session variable.
Thanks all.
Jon
As long as the Assembly is loaded in the scope of the Session, it will have access.
Although this type of tight coupling isn't really recommended.
You should be able to use HttpContext.Current.Session
Edit
While yes I agree you should not tightly couple your Business Logic DAL or etc assemblies to ASP.Net session. There are plenty of valid cases for accessing HTTP Context outside of a web project.
Web Controls is probably one of the best examples, reusable HTTP modules, etc..
Now one option, if you want to have your DLL pull the stuff from Session, is to abstract out session. So you could define an interface like IStorage, that your library will know how to use. Then you can have a SessionStorage or MemoryStorage class and use IoC to inject the appropriate class into your library classes. This gives you the freedom to code it how you wanted it to be coded without tying your code to Session. Oh and one other benefit if done properly can be used to not tie your code to the session on the web either.
You can always use HttpContext.Current.Session in your DLL but this is considered as bad practice. A better approach would be to pass the values stored in the session dictionary to your DLL instead of it referencing the session. Another benefit you will gain is that the code in your DLL won't be coupled to the ASP.NET runtime meaning it will be easier to test.
As said by the others, you can always use HttpContext.Current.Session in your DLL, I assume it's your BAL, but you need to be really carefull. What if your DLL is later consumed by a windows service, or some other app that doesn't have an HTTPContext? Whenever I've done this it's always been in a property get method where I wrap the attempt to access HttpContext.Current.Session in a try catch block and if anything goes wrong I repull the needed data from the db.
Do not use HttpContext.Current.Session as your dll will not run always with the Web Application. It may run with any other application like Windows,Console itc.
It is better to use a Method which is actully accept a parameter, which will come form Session Value, if you are using ASP.Net Application, otherwise there will not be any dependency of the application. If your dll project already developed and you are trying to modify the exsiting business logic then no, dont modify your exsiting method, use an Overload method.