I refactored an attribute, which implements Basic Http Authentication in the Web api, to have DI as follows:
public class BasicHttpAuthAttribute : ActionFilterAttribute
{
private readonly ILoginManager _manager;
public BasicHttpAuthAttribute(ILoginManager manager)
{
this._manager = manager;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Content = new StringContent("Missing Auth-Token");
}
else
{
var authToken = actionContext.Request.Headers.Authorization.Parameter;
var decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));
string userName = decodedToken.Substring(0, decodedToken.IndexOf(":"));
string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);
UserInfo user;
if (_manager.LoginPasswordMatch(userName, password, out user))
{
var apiUser = new ApiUser(user.UserID);
HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(apiUser), new string[]{});
base.OnActionExecuting(actionContext);
}
else
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Content = new StringContent("Invalid username or password");
}
}
}
}
Before the refactoring, I was creating an instance of the LoginManager (which itself did not have DI so I could create an instance using a ctor) inside OnActionExecuting. The problem after refactoring is that the build fails because when I apply the filter to a WebApi method, it is expecting an argument there.
How do I implement DI in this case as the LoginManager itself takes a ILoginRepository in its constructor? Is it even possible?
It's not easy to do because the way attributes are treated in Web API is a bit different than what you might expect. First of all they are created at various point in time, and secondly they are cached.
With that said, rather than injection through a constructor, the easiest way is to achieve DI is to call the DI framework of your choice at processing time, and retrieving the dependency then, i.e. inside your onActionExecuting:
var s = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IService));
The easiest option is to make it so your constructor does not require the parameter, but use a different form of injection instead. Exactly how you do that depends on what DI container you're using. With Unity, for example, you can just create a default constructor. Create another public method (I usually call it Initialize to be clear) and decorate it with the [InjectionMethod] attribute. Then, inside your constructor, just call container.BuildUp(this); That basically allows MVC to call the default constructor like it wants, but your InjectionMethod is always automatically called as a part of the construction process.
There are similar ways to do the same thing with other DI containers, but without knowing what you're using the Unit example is the easiest to explain.
You don't control the instantiation of the BasicHttpAuthAttribute so you can't use proper DI.
You can use a ServiceLocator in your attribute's constructor to give you the required dependencies or you can use the BuildUp functionality some containers provide for existing objects.
Unity does this to support BuildUp for 3rd party objects that you don't create yourself.
For your attribute that would mean to create a public writable property of type ILoginManager and tell the container to inject your manager into that property.
You don't have to pollute your attribute with the usage of the DependencyAttribute btw. Register your attribute type with the container and provide an InjectionProperty("NameOfThePropertyToInject") as a parameter for that registration.
Related
Consider the following example:
public class CommunicationClient : IClient
{
public CommunicationClient(IServerSettings settings) { ... }
// Code
}
public class SettingsManager : ISettingsManager
{
SettingsManager(IDbSettingManager manager)
// Code
public IDictionary<string, string> GetSettings() { ... }
}
Problem:
While performing registrations (using SimpleInjector), I need to provide values that are obtained from an instance of SetingsManager and fill ServerSettings instance (concrete type for IServerSettings) but if I call GetInstance<ISettingsManager> before registering CommunicationClient, it gives me an error that I cannot do that
Error:
The container can't be changed after the first call to GetInstance, GetAllInstances and Verify.)
One solution could be to inject ISettingsManager as a dependency to CommunicationClient but I really don't want to pass it as it would provide more than required information to it.
EDIT: Container Registration
container.Register(typeof(ICommunicationClient), typeof(CommunicationClient));
ISettingsManager settingsManager = container.GetInstance<ISettingsManager>();
string url = settingsManager.GetSetting("url");
string userName = settingsManager.GetSetting("username");
string password = settingsManager.GetSetting("password");
container.Register(typeof(IServerConfiguration), () =>
new ServerConfiguration(url, userName, password);
Any suggestions/alternative solutions on how to achieve above in a cleaner way? Thanks.
Simple Injector locks the container for further changes after its first use. This is an explicit design choice, which is described here. This means that you can't call Register after you called GetInstance, but there should never be a reason to do this. Or in other words, your configuration can always be rewritten in a way that you don't need this. In your case your configuration will probably look something like this:
var settingsManager = new SettingsManager(new SqlSettingManager("connStr"));
container.RegisterSingle<ISettingsManager>(settingsManager);
container.Register<ICommunicationClient, CommunicationClient>();
string url = settingsManager.GetSetting("url");
string userName = settingsManager.GetSetting("username");
string password = settingsManager.GetSetting("password");
container.Register<IServerConfiguration>(() =>
new ServerConfiguration(url, userName, password));
There you see that SettingsManager is not built-up by the container. When using a DI container, you are not required to let the DI container build up every instance for you. Letting the container auto-wire instances for you is done to lower the maintenance burden of your Composition Root and makes it easier to apply cross-cutting concerns (using decorators for instance) to groups of related classes. In the case of the SettingsManager and SqlSettingsManager classes, it is very unlikely that their constructor will change that often that it will increase the maintenance burden of your Composition Root. It's therefore perfectly fine to manually create those instances once.
If I understand correctly, to create your CommunicationClient class, you need to pass information that are retrieved by calling a method on an instance of your ISettingsManager, but you don't want to pass the ISettingsManager as a dependency to your CommunicationClient?
One solution for that would be to create, and register, a factory that would have a dependency on ISettingsManager and that would have a CreateClient method that would return the configured client.
public class CommunicationClientFactory : ICommunicationClientFactory
{
public CommunicationClientFactory(ISettingsManager settingsManager) {...}
public CreateClient() {...}
}
This way your CommunicationClient is not dependent on the ISettingsManager and you have just this factory that does the work of creating your instance.
Edit:
An alternative, if you don't want to create a factory for this, would be to have your CommunicationClient object be created in an "invalid" state, and have a method that would set the settings and make its state valid.
Something like:
public class CommunicationClient : IClient
{
public CommunicationClient() { ... }
// Code
CommunicationClient WithSettings(IServerSettings settings) { ... }
}
Of course, then you'd have to make sure that the user don't use it when the settings have not been passed yet, potentially sending an exception if that would be the case. I like this solution less, because it's less explicit that you NEED those settings to have your object in a correct state.
I have found out that I need the current logged in user data in nearly every class (controllers, view, HTML helpers, services and so on). So I thought about to create an "Ambient Context" instead of injecting an IUserService or the User directly.
My approach looks something like that.
public class Bootstrapper
{
public void Boot()
{
var container = new Container();
// the call to IUserService.GetUser is cached per Http request
// by using a dynamic proxy caching mechanism, that also handles cases where we want to
// invalidate a cache within an Http request
UserContext.ConfigureUser = container.GetInstance<IUserService>().GetUser;
}
}
public interface IUserService
{
User GetUser();
}
public class User
{
string Name { get; set; }
}
public class UserContext : AbstractFactoryBase<User>
{
public static Func<User> ConfigureUser = NotConfigured;
public static User ActiveUser { get { return ConfigureUser(); } }
}
public class AbstractFactoryBase<T>
{
protected static T NotConfigured()
{
throw new Exception(String.Format("{0} is not configured", typeof(T).Name));
}
}
Example usage:
public class Controller
{
public ActionResult Index()
{
var activeUser = UserContext.ActiveUser;
return View();
}
}
Is my approach correct or do I missing something? Do you have better solutions in mind?
UPDATE:
More Detail of the User class:
public class User
{
string Name { get; set; }
bool IsSuperUser { get; set;}
IEnumerable<AzManOperation> Operations { get; set}
}
In Controllers we need to check if an User is a SuperUser to only provide the SuperUser some extra functionality.
public class BaseController : Controller
{
private readonly IUserService _userService;
BaseControler(IUserService userService)
{
_userService = userService
}
public User ActiveUser
{
get { return _userService.GetUser(); }
}
}
In Views we check Operations to only show an edit or delete button if the user has the right to do so. A view never uses the DependencyResolver, but ViewBag or ViewModel. My idea here is to implementing a custom ViewBasePage and providing an ActiveUser property, so that Views have an easy accesss.
In HtmlHelpers we render controls depending on IsSuperUser and Operations (passing in the User object or using DependencyResolver).
In Service Classes we need those properties too. For instance to decide if a basket is valid or not (check if the User is allowed to buy articles that are not in a standard list). So the Service class depends on IUserService and calling GetUser().
In Action Filters to force the user to change his password (only if it is not a SuperUser and User.ForcePasswordChange is true). Here we use the DependencyResolver.
My wish is to have a more easily way to get the User object, instead of using DependencyResolver.Current.GetService().GetUser() or using things like ViewBag.ActiveUser = User.
The User object is an object that is almost everywhere needed to check permissions or the like.
In Views we check Operations to only show an edit or delete button if the user has the right to do so.
The view should not do this check. The Controller should return a view model to the view that contains boolean properties that state whether those buttons should be visible. Returning a bool with IsSuperUser already moves to much knownledge into the view. The view shouldn't know that it should show a certain button for a super user: that's up to the controller. The view should only be told what to display.
If almost all views have this code, there are ways to extract repetitive parts out of your views, for instance with partial views. If you're finding yourself repeating those properties over many view models, perhaps you should define an envelope view model (a generic view model that wraps the specific model as T). A controller can create its view model, while you create a service or cross-cutting concern that wraps it in your envelope.
In Service Classes we need those properties too. For instance to decide if a basket is valid or not
In this case you are talking about validation, which is a cross-cutting concern. You should use decorators to add this behavior instead.
This is MVC, right?
You're reinventing the wheel.
Add this method to your Global.asax.cs:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
var authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
var user = ticket.Name;
var identity = new GenericIdentity(user, "Forms");
var principal = new GenericPrincipal(identity, null);
Context.User = principal;
}
}
This example shows forms authentication which you can strip if you're using another mechanism. The key is these three lines:
var identity = new GenericIdentity(user, "Forms");
var principal = new GenericPrincipal(identity, null);
Context.User = principal;
GenericIdentity and GenericPrincipal can be replaced with anything you want as long as they implement the (trivial) IIdentity and IPrincipal interfaces. You can create your own implementations of these classes with whatever extra properties you need.
You can then access the authenticated user from all the things you listed - controllers, views, etc. - via HttpContext.Current.User (which is static).
If you created your own implementation of IPrincipal you can just cast that reference to your custom type.
You'll note that IPrincipal has a method called IsInRole, so you'd say:
if (HttpContext.Current.User.IsInRole("SuperUser"))
TL;DR - you are overengineering something ASP.NET has already solved, and I'd have an aneurysm if I saw the types you're proposing in a production application.
I think the easiest and maintainable solution is to create a static class CurrentUserProvider which has only one method Get(HttpContextBase) that returns the current user, behind the scene you can use the DependencyResolver to get the service that actually returns the user. Then where you need the CurrentUser you can call CurrentUserProvider.Get(context) and do whatever custom logic you need to perform.
The other solution that you are trying to do is injecting the service in the base controller constructor which is okay if you have handful of controllers, it would become an issue if you have quite a number of controllers and not all of the controllers requires that service. Writing tests for those controller would be such pain in the neck, because you have to create stubs/mocks for that service for all your controller tests. Maybe you can use property injection instead of constructor to address it.
You can use the same property injection for Filters too.
Now, the remaining two are the view and the helper. For View you can create special base class that inherits from WebViewPage/ViewPage and use the IViewActivator to inject the service and the same applies for the helpers, create helpers that inherits from system helpers and use those in your base controllers and views.
I think the second approach is bit cumbersome and it does not add that much value to do all those custom things.
So my suggestion is to go with the first.
I've run into an interesting design issue with a class library I am writing. I have a custom implementation of the AuthorizeAttribute that I want clients to be able to use like this:
[Protected("permission_name")]
In the above code, PermissionAttribute inherits from AuthorizeAttribute and uses a local default (DefaultContext created using HttpContext).
Behind the scenes, the attribute uses a SecurityService to check users, roles and permissions against (the SecurityService itself uses a client-provided persistence service that they can wire up in the composition root of their app).
So my attributes need a reference to the SecurityService to function. Since Attribute constructors can only have compile-time constants, I cannot use constructor injection.
I don't want to force my clients to use a DI framework - they should be able to discover and wire up the necessary dependencies in their composition root without using an IoC library, if they so choose.
Here are my options:
Have the library use a singleton SecurityService.
Use property injection, which would work but
it would make the dependency seem optional, which it is not and
I don't know where I can do property injection in an MVC app on an authorize attribute.
A possible solution to 2. above is to do set an instance of SecurityService as a static property on the attribute at application startup and use a guard clause to prevent it from being set more than once, like this:
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
The SecurityService could be an abstract service facade so that it can be extended/replaced by a different implementation.
Is there a better way to solve this problem?
UPDATE: Adding some code to show how I am going to do it:
Add a public property on the attribute that returns the permission name:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
Setup an authorization filter and configure dependency via Ninject (if using Ninject):
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
Ohhh it's...beautiful sniffle
With ASP.NET MVC 3 you could use constructor injection with action filters thanks to the new IFilterProvider. This way you no longer need to decorate your controller actions with action filters. You could apply them thanks to this interface and using a marker attribute.
And if you don't wanna bother implementing it manually you could always use an existing DI framework such as Ninject which provides a fluent way to define action filter dependencies.
My applications inherit from a base Application class that exposes the IOC container.
public interface IInjectableApplication
{
IUnityContainer Container { get; }
}
Then I have a base attribute class, which is aware of this
public abstract IocAwareActionFilterAttribute : ActionFilterAttribute{
protected T ResolveItem<T>(ResultExecutedContext context)
{
var app = context.HttpContext.ApplicationInstance as IInjectableApplication;
if (app == null) { throw new NullReferenceException("Application is not IInjectable."); }
T c = (T)app.Container.Resolve(typeof(T));
if (c == null) { throw new NullReferenceException(string.Format("Could not find injected {0}.", typeof(T).FullName)); }
return c;
}
}
While this is not true Injection, since Attributes aren't constructed 'normally', this provides a similar behavior. No reason it should not be adaptable to other IOCs
Consider a method in a .NET assembly:
public static string GetSecurityContextUserName()
{
//extract the username from request
string sUser = HttpContext.Current.User.Identity.Name;
//everything after the domain
sUser = sUser.Substring(sUser.IndexOf("\\") + 1).ToLower();
return sUser;
}
I'd like to call this method from a unit test using the Moq framework. This assembly is part of a webforms solution. The unit test looks like this, but I am missing the Moq code.
//arrange
string ADAccount = "BUGSBUNNY";
string fullADName = "LOONEYTUNES\BUGSBUNNY";
//act
//need to mock up the HttpContext here somehow -- using Moq.
string foundUserName = MyIdentityBL.GetSecurityContextUserName();
//assert
Assert.AreEqual(foundUserName, ADAccount, true, "Should have been the same User Identity.");
Question:
How can I use Moq to arrange a fake HttpContext object with some value like 'MyDomain\MyUser'?
How do I associate that fake with my call into my static method at MyIdentityBL.GetSecurityContextUserName()?
Do you have any suggestions on how to improve this code/architecture?
Webforms is notoriously untestable for this exact reason - a lot of code can rely on static classes in the asp.net pipeline.
In order to test this with Moq, you need to refactor your GetSecurityContextUserName() method to use dependency injection with an HttpContextBase object.
HttpContextWrapper resides in System.Web.Abstractions, which ships with .Net 3.5. It is a wrapper for the HttpContext class, and extends HttpContextBase, and you can construct an HttpContextWrapper just like this:
var wrapper = new HttpContextWrapper(HttpContext.Current);
Even better, you can mock an HttpContextBase and set up your expectations on it using Moq. Including the logged in user, etc.
var mockContext = new Mock<HttpContextBase>();
With this in place, you can call GetSecurityContextUserName(mockContext.Object), and your application is much less coupled to the static WebForms HttpContext. If you're going to be doing a lot of tests that rely on a mocked context, I highly suggest taking a look at Scott Hanselman's MvcMockHelpers class, which has a version for use with Moq. It conveniently handles a lot of the setup necessary. And despite the name, you don't need to be doing it with MVC - I use it successfully with webforms apps when I can refactor them to use HttpContextBase.
In general for ASP.NET unit testing, rather than accessing HttpContext.Current you should have a property of type HttpContextBase whose value is set by dependency injection (such as in the answer provided by Womp).
However, for testing security related functions I would recommend using Thread.CurrentThread.Principal (instead of HttpContext.Current.User). Using Thread.CurrentThread has the advantage of also being reusable outside a web context (and works the same in a web context because the ASP.NET framework always sets both values the same).
To then test Thread.CurrentThread.Principal I usually use a scope class that sets the Thread.CurrentThread to a test value and then resets on dispose:
using (new UserResetScope("LOONEYTUNES\BUGSBUNNY")) {
// Put test here -- CurrentThread.Principal is reset when PrincipalScope is disposed
}
This fits well with the standard .NET security component -- where a component has a known interface (IPrincipal) and location (Thread.CurrentThread.Principal) -- and will work with any code that correctly uses/checks against Thread.CurrentThread.Principal.
A base scope class would be something like the following (adjust as necessary for things like adding roles):
class UserResetScope : IDisposable {
private IPrincipal originalUser;
public UserResetScope(string newUserName) {
originalUser = Thread.CurrentPrincipal;
var newUser = new GenericPrincipal(new GenericIdentity(newUserName), new string[0]);
Thread.CurrentPrincipal = newUser;
}
public IPrincipal OriginalUser { get { return this.originalUser; } }
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
Thread.CurrentPrincipal = originalUser;
}
}
}
Another alternative is, instead of using the standard security component location, write your app to use injected security details, e.g. add an ISecurityContext property with a GetCurrentUser() method or similar, and then use that consistently throughout your application -- but if you are going to do this in the context of a web application then you might as well use the pre-built injected context, HttpContextBase.
[TestInitialize]
public void TestInit()
{
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
}
Also you can moq like below
var controllerContext = new Mock<ControllerContext>();
controllerContext.SetupGet(p => p.HttpContext.Session["User"]).Returns(TestGetUser);
controllerContext.SetupGet(p => p.HttpContext.Request.Url).Returns(new Uri("http://web1.ml.loc"));
In ASP.NET MVC Core I use the following code to test controllers, which depend on HttpContext:
var controller = new HomeController();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
This is a sample unit test:
[Test]
public void Test_HomeController_Index()
{
// Arrange
var controller = new HomeController();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
// Act
var result = controller.Index();
// Assert
var viewResult = result as ViewResult;
Assert.IsNotNull(viewResult);
}
Have a look at this
http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx
Using httpSimulator class,You will be able to do pass a HttpContext to handler
HttpSimulator sim = new HttpSimulator("/", #"C:\intepub\?")
.SimulateRequest(new Uri("http://localhost:54331/FileHandler.ashx?
ticket=" + myticket + "&fileName=" + path));
FileHandler fh = new FileHandler();
fh.ProcessRequest(HttpContext.Current);
HttpSimulator implement what we need to get a HttpContext instance. So you don't need to use Moq here.
If you're using the CLR security model (as we do) then you'll need to use some abstracted functions to get and set the current principal if you want to allow testing, and use these whenever getting or setting the principal. Doing this allows you to get/set the principal wherever is relevant (typically on HttpContext on the web, and on the current thread elsewhere like unit tests). This would look something like:
public static IPrincipal GetCurrentPrincipal()
{
return HttpContext.Current != null ?
HttpContext.Current.User :
Thread.CurrentThread.Principal;
}
public static void SetCurrentPrincipal(IPrincipal principal)
{
if (HttpContext.Current != null) HttpContext.Current.User = principal'
Thread.CurrentThread.Principal = principal;
}
If you use a custom principal then these can be fairly nicely integrated into its interface, for example below Current would call GetCurrentPrincipal and SetAsCurrent would call SetCurrentPrincipal.
public class MyCustomPrincipal : IPrincipal
{
public MyCustomPrincipal Current { get; }
public bool HasCurrent { get; }
public void SetAsCurrent();
}
This is not really related in using Moq for unit testing of what you need.
Generally we at work have a layered architecture, where the code on the presentation layer is really just for arranging things for being displayed on the UI. This kind of code is not covered with unit tests. All the rest of the logic resides on the business layer, which doesn't have to have any dependency on the presentation layer (i.e. UI specific references such as the HttpContext) since the UI may also be a WinForms application and not necessarily a web application.
In this way you can avoid to mess around with Mock frameworks, trying to simulate HttpRequests etc...although often it may still be necessary.
I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
The problem is that I don't want to write
BusinessProducts bp = new BusinessProducts(dataContextImplementation);
I would continue to write
BusinessProducts bp = new BusinessProducts();
because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.
Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?
I am coding in c# but alternatives from other languages is welcome
I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.
So my business products class would look like:
public class BusinessProducts
{
private IDataContextFactory DataContextFactory { get; set; } // my interface
public BusinessProducts() : this(null) {}
public BusinessProducts( IDataContextFactory factory )
{
this.DataContext = factory ?? new BusinessProductsDataContextFactory();
}
public void DoSomething()
{
using (DataContext dc = this.DataContextFactory().CreateDataContext())
{
...
}
}
An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.
You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.
I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = new SolidDataContext();
}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
}
This way you can use DI for overriding the default instance in unit testing testing.
Your feelings, while valid, are misplaced.
The Dependency Injection pattern is a direct application of the Inversion of Control principle.
This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.
As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.
There are two distinct cases here:
In production code you will never write
new BusinessProducts(dataContextImplementation)
because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.
In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.
http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.
Generally the framework itself will have the logic to build up the entire object tree. For example, instead of
new SomeObjectO(diContext)
you would call the framework like this:
DIFramework.GetNew<SomeObjectO>();
or
DIFramework.Get<SomeObject>();
Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.
If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.
BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();
If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.
There's a technique called poor man's DI that looks like this
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts() : this(new DataContext()) {}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to #tvanfosson but a lot simplier.
I second the recommendation for Windsor
My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.
you can also look at windsor for IoC .