C#: Pass Data from Controller to Application Layer to DBContext Layer - c#

I would like to pass global custom data from API Level to Application Service, to Repository and DB Context layer, without using parameters in every method.
1) One method is HttpContextAccessor.
Curious if there is any other global parameter embedded in Net Core, or is this the only known strategy? We are passing auditable data, CreateBy, ModifiedDate, but may extend it other properties. We have 100+ apis, application methods, repositories, and trying to prevent passing around a parameter.
_httpContextAccessor.HttpContext.Items["TestKey"] = "SampleData";
DBContext:
public class AuditableDbContext: DbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public AuditableDbContext(DbContextOptions<AuditableDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor;
}
Custom Data changes based on application behavior and user interaction.

One problem with using context aware objects across multiple layers is the dependency to that context.
It makes it really hard to understand the code in the long run, and, most importantly, it makes it harder to unit test.
Imagine you rely on an HttpContext item coming from your controller in another layer. The unit test of that layer would now have to mimic the controller and set the item on the context to produce a proper state.
Having multiple parameters getting passed around everywhere is bad, too, true.
One way of solving it would be a simple Poco object to store the state and pass that around, that would make unit testing simple and also reduce the number of parameters of methods in all layers.
public class RequestState
{
public User CreateBy { get; }
...
}
The controller would initiate the state object and all layers would use it...
Another way would be to rely on the DI framework and use a scoped lifetime object which gets injected into all layers which you then can abuse to store your state information.
That's pretty similar to http context but at least its your own thing and you can do whatever you want with it and also add strongly typed properties instead of an Items collection.
In your startup, you'd inject the scope object with Scoped lifetime.
You inject the object into your controller and all other classes (works only if those classes are also scoped or transient).

Related

ASP.NET Core and ViewModelFactory

Hello, I'm trying to implement a ViewModelFactory "pattern" and I was wondering what's the best way to achieve it, considering the constraints of the current IoC container.
public class UserCreateViewModelFactory
{
private readonly DbContext db;
public UserCreateViewModelFactory(DbContext db){ this.db = db;}
public void Create(CreateUserViewModel viewModel)
{
//Creates the user
}
}
I have the above class easily injected into my controllers ctor. The head ache will come when I need more ViewModelBuilders, So I want to avoid two things:
Bloat ctor with injections
Bloat container with registrations
I want to be able to inject an IViewModelFactory on my controller and then using it like this:
[HttpGet]
public IActionResult GetUsers(int id)
{
return View(viewModelFactory.Build<GetUserViewModel>(id));
}
Notice that on calling Build(T) it has to call the correct IViewModelFactory implementation.
I know that StructureMap container support binding the concrete implementations to the corresponding interface but I'm trying to come up with a solution without having to add another dependecy to the project.
I think if you have builders for building viewmodels, then factory is extra layer of abstraction which simply can be dropped off.
Because you know the type of created viewmodel at compile time you can just inject a builder you need to the controller constructor.
If your controller create a lot of viewmodels and you end up with a lot of builders you need to inject - this can be considered as a sign of violation of Single Responsibility Principle. In that case you need to separate logic of controller to different controllers.
So I want to avoid two things:
Bloat ctor with injections
Separate class with bloated constructor to another classes with more specific responsibility which takes smaller amount of dependencies.
Or wrap dependencies with one or two, three classes based on their relation
Bloat container with registrations
This cannot be a problem, because dependency containers is usually designed to register whole "object graph" of your application
After sometime researching, I finally came up with a good solution for the this problem.
The solution is basically extending the default IoC capabilities through an IServiceCollection.ConnectImplementations() extension method.
During registration I'll search my concrete classes and connect them with its respective interfaces (like other containers). Then I use a Mediator/Proxy that has IServiceCollection injected and knows which concrete class should be building the view model.
The full solution is better explained by this gist I've created.

Ninject and DbContext

Building a app with EF 6 and Ninject 3.2.2 I'm having some trouble wrapping my head around how to access the DbContext in a intelligent way.
As I understand in the newer versions of Ninject only constructor injection is encouraged. As EF 6, itself is repo and unit of work I'm not doing any abstractions on top of EF.
If would like to be able to use multiple small units of works so injecting the DbContext (uow) into every class that needs it is not going to work.
In a non IoC way I would do like this:
Using(var db = new DbContext){}
How do achieve this using Ninject as I no longer can do kernel.get in my using block...
I'd consider two approaches:
Create general DbContext, which can be hidden behind an interface:
public interface IPortalContext : IDisposable
{
DbSet<User> Users { get; }
DbContext Context { get; }
}
public class PortalContext : DbContext, IPortalContext
{
public PortalContext()
: base("PortalConnectionString")
{
}
public virtual DbSet<User> Users { get; set; }
}
then you can inject your context to the constructor without problem.
Create many small contexts which can be used in different scenarios and classes.
I don't think that first approach is bad since it only encapsulates your DbSets and DbContext making it easier to inject and test. You don't make any unnecessary layers above EF and whole interface seems quite transparent.
Anyway this approach is better than making whole IRepository<T> stuff to access another repository...
I'm not sure what you mean by "multiple small unit of works", but just for exposure, this is what I've done in a recent application:
Divided the domain in small bounded contexts (this is more of a conceptual step)
Each bounded context has: a context, a repository, a repository factory
Each context implements an IContext and a BaseContext that gives basic methods and common properties (IContext will be useful for mocking)
Each repository takes the relative context as a constructor paramenter
This is an example of a repository factory
public class CartRepositoryFactory : IRepositoryFactory
{
public IRepository Generate(CartContext ctx)
{
return new CartRepository(ctx);
}
}
At the application service layer, I inject a UoW and the repository factory that I need
If I want to work with several different context in one service, I simply create another service and combine the services that I need, injecting them
You might be asking, but why?!? This is madness!!
Well, because if the Repository manages the DbContext, then I can only do one operation per class instantiation. This allows me to open a DbContext and make several calls to the Repository.
Of course now you have the same problem at application service level, you can only call one method per instantiation, but it's far easier to manage.
Ultimately it all comes down to your taste: would you rather have a thin service or a thin repository?

MVC Unit Testing with Unity Container

I just have a quick question. Im trying to use Unity with my asp.net MVC project. Im coming across a problem when using the Unit of Work pattern with an EF context.
Say i inject the uow in the constructor, but have 4 or 5 actions in the controller that need to use the UnitOfWork in a using statement. This isnt going to work! Because Id have to do a
new UnitOfWork() in each action method.
should i be injecting a UnitOfWork into each action method? or into just the constructor? or should I even be injecting this at all!! The problem im facing is that i want to be able to unit test my controller with Mock data, and i can only do this if I inject the UnitOfWork or the DBContext.
Inject factory instead. This way you still achieve separation of concerns and loose coupling, yet you won't face any issues with using statements:
private IUnitOfWorkFactory factory;
public MyController(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public ActionResult MyAction()
{
using (var uow = factory.CreateUnitOfWork())
{
// ...
}
}
Edit:
Natural advantage of such approach is its configurability - you can register whichever factory you like to serve different controllers and wire it up at composition root:
// Note: this isn't unity syntax, but I hope my point is clear
container.Register<ISessionFactory, ReusableSessionFactory>("Reusable");
container.Register<ISessionFactory, FreshSessionFactory>("Fresh");
container.Register<IController, LoginController>().With("Fresh");
container.Register<IController, HomeController>().With("Reusable");
Now,
LoginController will use factory that under the hood serves new session upon each request
HomeController on the other hand will reuse the same session for all its lifespan
It's worth noting that from the controller point of view, it's irrelevant which factory serves the session as it's a mere implementation detail. That's why we hide session factory dependency behind abstraction (interface in this example) and perform all the object-to-dependency binding at application's root.
If I understand correctly you simply want to be able to test the UOW with something like Moq?
In that case for good design principles and proper separation of concerns you should create a base context for your database that each repository class uses.
Then you should create a repository interface for each domain model entity. Then you can implement the interface in a seperate repository library (this way you can implement a POCO model)
Finally you either create a service layer between your domain objects and your action methods or just use the required repository interfaces within the action methods.
I answer it like this because it depends on your application infrastructure. If you have no service layer then the best practice is to do the following:
public class AccountController : Controller
{
private readonly IAccountRepository _accountrepository;
public AccountController(IAccountRepository repository)
{
_accountrepository = repository;
}
}
I hope this helps.

I know how to use dependency injection but I recognize no practical advantage for it

It is about this (Inject the dependency)
private readonly ICustomerService _customerService;
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
versus this (Create the dependency)
private readonly ICustomerService _customerService;
public Billing()
{
_customerService = new CustomerService();
}
The latter sample so they say is bad because... it violates DI...of course nothing is injected... but what if DI would not exist, what is so bad that the CustomerService is created manually from the Billing class? I see no practical advantage concerning exchangeability of the Service interface.
I ask for a practical example with source code may it be a unit test or showing a practical solution why it is so much more loose coupling.
Anyone keen enough to show his DI muscles and why it has a practical right to exist and be applied?
UPDATE
So people have not to read all up I will write here my short experience:
DI as a pattern has a practical usage. To follow DI by not injecting all services manually (a poor mans DI tool so they say...) use a DI framework like LightCore/Unity but be sure you use the right tool for the appropriate job. This is what I did not;-) Developing a mvvm/wpf application I have other requirements the LightCore/Unity tool could not support they even were a barrier. My solutions was to use MEFEDMVVM with which I am happy. Now my services are automatically injected at runtime not at startup time.:-)
Understanding the how and understanding the why are very different things..
One of the biggest benefits of DI is for unit testing. In your second example it's impossible to unit test Billing without also testing CustomerService (and also testing any further dependencies in the chain). In that case you're not unit testing, you're integration testing! If you want a good rationale for using DI, you need not look any further than a rationale for unit testing..
Imagine that CustomerService connects to your CRM system and your database. It creates a whole bunch of network connections to retrieve data about the customer and maybe reads additional things from the database to augment that before returning the data to the Billing class to use in its calculation.
Now you want to unit test Billing to make sure the calculations it's making are correct (you don't want to send out wrong bills right?)
How will you unit test Billing if its constructor is tied to a class that requires connections to a real CRM system and database? Wouldn't it be better to inject that dependency as an interface, easily allowing you to provide a mock version for your tests?
That is why DI is useful.
DI Comes in useful, when you want to pass different implementations of the Interface to your class, for example: Unit Testing.
Say your Billing constructor is an MVC controller's constructor, and your CustomerService took some form of IDataContext as a parameter.
Global.asax
// Does the binding
ICustomerService binds to CustomerService
IDataContext binds to EntityFrameworkContext
CustomerService
private IDataContext _datacontext;
public CustomerService(IDataContext dataContext)
{
_dataContext = dataContext;
}
public AddCustomer(Customer entity)
{
this._dataContext.Customers.Add(entity);
this._dataContext.SaveChanges;
}
MVC Controller
private ICustomerService _customerService;
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
public ActionResult NewCustomer()
{
Customer customer = new Customer(){ Name = "test" };
this._customerService.AddCustomer(customer);
return View();
}
Say you wanted to unit test your Services, or Controllers. You would pass in the CustomerServices, but you would pass in a fake implementation of the EntityFrameWorkContext.
So a FakeDbContext, that implements IDataContext, is passed to customer services.
The FakeDbContext may just store the entities in Lists or a more elaborate storage mechanism, the point being, you can inject different implementations of dependencies, which allows you to alter the behaviour of one component without having to modify your code elsewhere.
In my experience it is not only about avoiding integration test (but that is a very important point too). Instantiating classes on the inside can create a lot of work unit testing. A class like CustomerService might depend on an open Database connection, configuration files, services being available and a lot of other stuff, that you should not have to know about, when your job is to test the Billing class only.
That being said, sometimes it is a pain always to inject everything. Injection frameworks might lighten that load, but I'm not at big fan. Another kind stackoverflow user pointed me to what he called "poor mans injection". Basically it consists of two constructor overloads: One constructor with the injected interface, and one without. The one without does nothing but instantiate a concrete class that implements the interface, and pass it to the other constructor. It goes something like this:
public class Billing
{
ICustomerService _customerService;
public Billing():this(new CustomerService()) {}
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
}
This way you have an way to inject when testing AND a way to construct the class with a default implementation of the interface. Not everybody loves this pattern, but I find it practical for some scenarios.

Passing web context to a 'service' in ASP MVC app

I'm trying to work out a way of passing the web current http context to a service class (or initialising the class with a reference to it). I am doing this to abstract the rest of the app away from needing to know anything about the http context.
I also want the service to be testable using TDD, probably using one of the Mockable frameworks. Hence it would be preferable to use an interface rather than an actual class.
An example of what I'd like to achieve:
class WebInstanceService
{
private IHttpContext _Context;
public WebInstanceService( ... , IHttpContext HttpContext )
{
....
_Context = HttpContext;
}
// Methods...
public string GetInstanceVariable(string VariableName)
{
return _Context.Current.Session[VariableName];
}
}
One of the main issues I have is that there is no IHttpContext, the .net http context is a subclass of an abstract class which can't be mocked (easily?).
Another issue is that I can't initialise global instances of the class as then the context won't be relevant for most requests.
I could make the class static, and require the Context to be passed to each function as it is called i.e.
public static string GetInstanceVariable(string VariableName, HttpContext Context)
{ ... }
but this doesn't make the class any easier to test, I still need to create an HttpContext and additionally any non-web-aware services which want to use this class suddenly need to be able to retrieve the Context requiring them to be closely coupled to the web server - the whole reason for wanting to create this class in the first place.
I'm open to ALL suggestions - particularly those which people know facilitate easy tdd testing. How would people suggest I tackle this problem?
Cheers
This is why HttpContextBase and HttpContextWrapper were introduced. You probably want to use HttpContextBase and when passing the real context in, use new HttpContextWrapper( httpContext ), although, I think that what is available to you in the controller is already of type HttpContextBase. I would create one of these in my controller each time rather than trying to reference the current context from the static, global HttpContext.Current instance. If you need it in your view, pass a reference to your strongly typed context in ViewData.
I mock up HttpContextBase frequently in my tests.
class WebInstanceService
{
private HttpContextBase _Context;
public WebInstanceService( ... , HttpContextBase HttpContext )
{
....
_Context = HttpContext;
}
// Methods...
public string GetInstanceVariable(string VariableName)
{
return _Context.Session[VariableName];
}
}
What we do is spin one of these up http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx
Easy as pie, just instanciate an HttpSimulator and fill in the values, and HttpContext.Current gets filled up with whatever you specify.
IHttpContext is something that is in MVC, and aparently one day will be in webforms. Hopefully that day will be .net 4
ASP.NET comes with System.Web.Abstractions that include HttpContextBase that you can use for dealing with the HttpContext in a testing situation.
I would personally abstract away the direct dependency on the HttpContext.

Categories