How to solve base Controller dependency injection for testing purposes? - c#

I have implemented my mvc base controller called DefaultController using dependency injection pattern in order to be able to construct test cases. Example below:
public class DefaultController : Controller
{
protected readonly ISessionHelper _sessionHelper;
string _thisUserOpenID;
protected IUsersRepository _UserRepository;
...
public DefaultController()
{ } //not for testing
public DefaultController(ISessionHelper session, IUserRepository repo)
{
_sessionHelper=session;
_UserRepository = repo;
}
}
Then I have my controllers using this controller, homecontroller, usercontroller, etc.
Now, building some test cases I found myself in a situation where I don't know how to actually use the injection dependency pattern.
[TestMethod]
public void Welcome_Message_In_ViewData_Has_Coockie_User_Display_Name()
{
// Below I want to insert FakeRepositories using
//ISessionHelper and so on. but the constructor
//for homecontroller don't have it.
HomeController controller = new HomeController();
Any ideas?

Your HomeController needs to have a matching "injectable" constructor, which would then call the base constructor.
public HomeController(ISessionHelper session, IUserRepository repo)
: base(session, repo)
{
}
Now, in your test, you would create your HomeController using that constructor, and pass in a mocked up session and user repository. Speaking of mocking, you might also be interested in Scott Hanselman's MvcMockHelpers classes, with code for many popular mocking frameworks.

I don't see why you have two constructors. You should only have one, get rid of the constructor with no parameters. Using a DI framework like Castle Windsor, or my preferred one, Autofac will handle all of this for you. Then as far as testing is concerned use something like Moq. Ie
public DefaultController(ISessionHelper session, IUserRepository repo)
{
_sessionHelper = session;
_UserRepository = repo;
}
Register DefaultController, ISessionHelper and IUserRepository with your DI framework. Something along the lines of:
Register(new DefaultController()); (it is something like that in Autofac)
Register<SessionHelper>().As<ISessionHelper>();
Register<UserRepository>().As<IUserRepository>();
That way, you can pull DefaultController from the container and the DI framework will inject the two parameters for you. I wrap up a static method to access my DI container, it looks like:
var controller = IoC.Resolve<DefaultController>();
Basically head over to Autofac and have a look. There's also a web module for registering your Controllers for you.
Then for testing just use Moq, or find some form of "AutoMocker" (google it). I would do:
var session = new Mock<ISessionHelper>();
var repo = new Mock<IUserRepository>();
repo.Setup(s => s.FindById(123)).Returns(new User());
var conroller = new DefaultController(session.Object, repo.Object);
controller.Execute();
Also ewww repositories. With .Net and generics etc... just create yourself an nice ISession.
var session = IoC.Resolve<ISession>();
var user1 = session.Get<User>(123);
var user2 = session.Get<User>(u => u.Username == "admin");
session.Update(user3);
Means you only need to pass in one thing and you can use it for whatever. Rather than having to pass in sometimes many repositories. Also sets you up nicely for the Unit Of Work pattern.

Related

How to inject User Identity in Asp.Net web api controller constructor?

I have a controller decorated with [Authorize] attribute. I would like to accomplish the following so that I don't have to repeatedly create repository obj and pass currentUser in each method:
[Authorize]
public class HomeController : ApiController
{
Repository repo;
public HomeController()
{
var userName = User.Identity.IsAuthenticated ? User.Identity.Name : null;
repo = new Repository(userName);
}
}
I know User.Identity is not available in constructor or in Initialize method.
What is the best practice to inject authenticated user in controller constructor.
If we use dependency injection - while registering our custom created UserResolverService inside WebApiConfig.cs in Register method - User.Identity is not available at this point as well.
This is a very common issue with web api but somehow couldn't find any article showing proper solution.
Is it really achievable and if yes - can you please provide some sample code?
Here is how I worked around this (not sure how appropriate this method is, but it works).
In your BaseContoller (a controller from which all other controllers inherit from) create instance of Repository like so:
private Repository _Repository;
private Repository Repository
{
get
{
_Repository.InjectUsername(User.Identity.Name); // value is already available here
return _Repository;
}
set
{
_Repository = new Repository();
}
}
Notice how your Repository has InjectUsername method. That method will simple assign passed parameter to some Repository's property, like so:
public class Repository
{
private string Username { get; set; }
public void InjectUsername(string username)
{
Username = username;
}
}
Every time you will call some method in repository from a controller action you will inject usrename which will already exist, and you won't have to duplicate code by passing username to every method in repository every time you call it.
You can register a factory delegate and get user identity from HttpContext.Current.
Here's a sample code for simpleinjector
container.Register<IPrincipal>(() => HttpContext.Current.User);

How to register a service in ASP.NET Core that is created by a factory?

I am getting the following error:
Unable to resolve service for type 'IMyRepository' while attempting to activate 'MyController'.
I understand that my application is failing on the dependency injection.
However I'm not sure how to correct this error.
My IMyRepository looks lie this:
public interface IMyRepository
{
public Delete(Guid Id);
public Get(Guid Id);
//etc..
}
We set the following interface up when we created the unit tests.
public IMyRepositoryFactory
{
IRepository CreateRepository();
}
The constructor in my Controller:
private readonly IRepository _repo;
public MyController(IRepository repo)
{
_repo = repo;
}
I can pass the factory into the constructor, however that would require me to redo the unit testing modules since they are all passing IRepository to the controller.
Ex. (In Startup ConfigureServices)
services.AddTransient<IMyRepositoryFactory, ConcreteRepositoryFactory>();
I would prefer to leave the controller constructors and testing classes as is. So is there a way to setup DI in this scenario (Where I am passing the IRepository to the controller)?
EDIT:
public class ConcreteRepositoryFactory : IMyRepositoryFactory
{
public ConcreteRepositoryFactory(string connString);
public IMyRepository CreateRepository();
}
I'm not exactly clear on what you're trying to achieve here. Simplistically, you need to bind an implementation of IMyRepository if you want to inject IMyRepository:
services.AddScoped<IMyRepository, MyRepository>();
If you're saying you want to inject the implementation via a factory, you can simply provide a factory to the service registration:
services.AddScoped<IMyRepository>(p =>
p.GetRequiredService<IMyRepositoryFactory>().CreateRepository());
You are adding a Transcient IMyRepositoryFactory linked to a ConcreteRepositoryFactory.
So you cannot inject a IRepository class in your controller, because asp.net Core doesn't know your IRepository class in the transcient injections.
You have to inject instead the ConcreteRepositoryFactory class to your controller like this :
public MyController(ConcreteRepositoryFactory repo)
And you can store in your readonly property as IMyRepositoryFactory _repo.

Mocking StandardKernal Interface with Ninject

I'm working on adding unit tests to some legacy ASP code with Moq and the Ninject.MockingKernal.
public class BaseController : Controller
{
private IAuthenticationManager authenticationManager;
public ILog log;
public BaseController()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
log = kernel.Get<ILog>();
}
}
The Log Interface:
public interface ILog
{
AuditTrail Create(AuditAction action, string description = null);
AuditTrail Create(AuditAction action, long reservationId, string description = null);
AuditTrail Create(IUser user, AuditAction action);
AuditTrail Create(IUser user, AuditAction action, string description = null);
AuditTrail Create(IUser user, AuditAction action, long reservationId, string description = null);
}
I'm trying to mock the log instance that is set up from the kernel. This log is inherited by other controllers and is not injected. I want to be able to return a mock object when it's requested, much like I would do in other cases (such as returning a mock DatabaseContext from a factory).
I've looked at this How to do Setup of mocks with Ninject's MockingKernel (moq) and the GitHub example: https://github.com/ninject/Ninject.MockingKernel/wiki/Examples, as well as many others.
From what I've gathered, I need to do something along these lines:
mockingKernal = new MoqMockingKernel();
mockingKernal.Bind<ILog>().To<Logging.Log>();
var foo = mockingKernal.GetMock<ILog>();
foo.Setup(x => x.Create(It.IsAny<AuditAction>(), It.IsAny<long>(), It.IsAny<string>()));
However, if I run this, I get an error System.ArgumentException: Object instance was not created by Moq. From what I can find online, this is caused by the class having a parameter in the constructor, but in this case, the Log class does not.
Am I approaching this in the correct way? And if I am, what am I doing wrong? Any help would be greatly appreciated
The above approach/design is going to cause all manner of head aches to maintain/test as the controller is tightly coupled to the kernel (IoC container) which basically does not allow one to be able to easily mock/replace it for testing.
Also note that the examples linked in question all have in common the ability to explicitly inject the dependencies into their subjects under test.
The above is basically using the kernel as a service locator.
Trying to put lipstick on that code may change its appearance but does nothing about the smell.
Ideally the design should be following the explicit dependency principle.
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
public class BaseController : Controller {
private IAuthenticationManager authenticationManager;
public ILog log;
public BaseController(ILog log, IAuthenticationManager authenticationManager) {
this.log = log;
this.authenticationManager = authenticationManager;
}
}
which would allow the dependencies to be mocked/faked/stubbed and injected into their dependents.
//Arrange
var logger = new Mock<ILog>();
logger
.Setup(_ => _.Create(It.IsAny<AuditAction>(), It.IsAny<long>(), It.IsAny<string>()))
.Return(new AuditTrail);
var controller = new BaseController(logger.Object, null);
//Act
//...
One should not be calling the container directly within classes but rather configure it at the composition root.
I suggest reviewing the current design and refactoring accordingly.

WebAPI DI Framework that understands HttpContext.User

I am looking for a DI framework that can satisfy this scenario:
Every Controller has a constructor like this
public ThisController( ThatRepository repo)
Every Repository has a controller like this:
public ThatRepository (DataSource ds)
There is one master DataSource, but that is never passed to the repository. Instead it needs:
MasterDataSource.WithUser ( httpContext?.User?.Identity?.Name )
Are there any DI frameworks for WebAPI that would support this out of the box?
I believe that you could use almost every DI container for such a purpose, by registering current HttpContext (or even the current user Identity) inside the container and then injecting it for constructing your DataSource instance.
Here it is a simple solution using HttpContext in SimpleInjector (you may easily port the code to any DI framework you like):
container.Register<HttpContextBase>(() =>
new HttpContextWrapper(HttpContext.Current),
Lifestyle.Scoped);
container.Register<DataSource>(() =>
{
var httpContext = container.GetInstance<HttpContextBase>();
return MasterDataSource.WithUser(httpContext?.User?.Identity?.Name);
},
Lifestyle.Scoped);
Abstract the HttpContext behind an interface you control and have your DI container of choice resolve that when needed.
public interface ICurrentUser {
string Name{get;}
}
A concrete implementation of that interface can look like...
public class UserProvider : ICurrentUser {
HttoContextBase httpContext;
UserProvider(){
httpContext = HttpContext.Current;
}
public string Name {
get{ return httpContext?.User?.Identity?.Name ?? string.Empty; }
}
}
You register your interface/contract with your DI container and resolve it when needed for your DataSource.
public void SomeSetupMethod(ICurrentUser user) {
MasterDataSource.WithUser(user?.Name);
}

dependency injection alternatives

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 .

Categories

Resources