Managing DbContext in WPF MVVM application - c#

I've been banging my head with this for days and still can't decide on which is the correct approach.
This question is targeting WPF specifically since as opposed to a web-application, many posts and articles online recommends a context per view-model approach and not a context per request.
I have a WPF MVVM application which is using an Entity-Framework DB first model.
here is an example of two models used in my app (created by EF Designer):
public partial class User
{
public User()
{
this.Role = new HashSet<Role>();
}
public string ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Role> Role { get; set; }
}
public class Role
{
public Role()
{
this.User = new HashSet<User>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<User> User { get; set; }
}
I've narrowed my options on how to handle this to the following:
1) Creating a DataAccess class which creates and disposes of the DbContext on each method call:
public class Dal
{
public User GetUserById(object userId)
{
using (var db = new DbEntities())
{
return db.User.Find(userId);
db.SaveChanges();
}
}
public void RemoveUser(User userToRemove)
{
using (var db = new DbEntities())
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
}
}
which I can use in my ViewModel as follows:
public class UserManagerViewModel : ObservableObject
{
private readonly Dal dal = new Dal();
// models...
//commands...
}
2) Similar to approach 1 but without the Using statements:
public class Dal : IDisposable
{
private readonly DbEntities db = new DbEntities();
public User GetUserById(object userId)
{
return db.User.Find(userId);
db.SaveChanges();
}
public void RemoveUser(User userToRemove)
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
public void Dispose()
{
db.SaveChanges();
}
}
The use is the same inside the ViewModel
3) Create a repository for each entity. Looks the same as the above options (also has the with or without the using dilemma), however every repository contains only methods related to its entity.
Afaik the use is the same as above inside my ViewModel.
4) Create a Unit-Of-Work class that will pass the appropriateRepository on demand:
public class UnitOfWork : IDisposable
{
private DbEntities db = new DbEntities();
private IUserRepository userRepository;
public IUserRepository UserRepository
{
get
{
return userRepository ?? new UsersRepository(db);
}
}
public void Save()
{
db.SaveChanges();
}
public void Dispose()
{
db.Dispose();
}
}
and use it inside my ViewModel as follows:
public class UserManagerViewModel : ObservableObject
{
private readonly UnitOfWork unit = new UnitOfWork();
// models...
//commands...
}
Which of the above approach (if any) is preferred in terms of in terms of data concurrency, better abstraction and layering and overall performance?
EDIT - Found the following paragraph in this article. :
When working with Windows Presentation Foundation (WPF) or Windows Forms, use a context instance per form. This lets you use change-tracking functionality that context provides.
However, it raises the question of whether I should create a DbContext object in my view-model or is it better to have a utility class such as my DAL class and reference it.

This is what dependency injection frameworks are designed to solve. Yes, it's yet another technology to add to your project, but once you start using DI you never look back.
The real problem here is that you're trying to make this decision in your view models when you really should be employing inversion of control and making the decision higher up. A WPF/MVVM application will want a context per-form so that changes are only submitted once a user is finished editing, and also to give the user the opportunity to cancel the changes. I know you're not using this in a web application but a well-designed architecture means you should be able to, in which case you'll want a context per request. You may want to write a console-app utility that populates the database with static data, in this case you may want a global/singleton context for performance and ease-of-use. Lastly, your unit tests also need to mock the context, probably on a per-test basis. All four of these cases should be set up in your injection framework and your view models should neither know or care about any of them.
Here's an example. I personally use Ninject, which is specifically designed for .NET. I also prefer NHibernate, although the choice of ORM is irrelevant here. I have session objects that have different scoping requirements, and this gets set up in a Ninject module that initializes my ORM classes:
var sessionBinding = Bind<ISession>().ToMethod(ctx =>
{
var session = ctx.Kernel.Get<INHibernateSessionFactoryBuilder>()
.GetSessionFactory()
.OpenSession();
return session;
});
if (this.SingleSession)
sessionBinding.InSingletonScope();
else if (this.WebSession)
sessionBinding.InRequestScope();
else
sessionBinding.InScope(ScreenScope);
This sets up the scoping for an ISession, which is the NHibernate equivalent of your context class. My repository classes, which manage the database objects in memory, contain a reference to the session they are associated with:
public class RepositoryManager : IRepositoryManager
{
[Inject]
public ISession Session { get; set; }
... etc...
{
The [Inject] attribute tells Ninject to populate this field automatically using the scoping rules I've set up. So far this is all happening in my domain classes, but it extends to my view model layer as well. In my scoping rules I pass in an object called "ScreenScope", and while I won't go into it here it basically means that any time I ask for a session object in my ScreenViewModel, or any view models that it has as members (including their own children) the same ISession object gets automatically created and passed in to all of them. By using DI scoping I don't even have to think about it, I just declare the members with the [Inject] attribute and it happens:
public class ScreenViewModel
{
[Inject] public CustomerService CustomerService { get; set; }
[Inject] public SalesService SalesService { get; set; }
[Inject] public BillService BillService { get; set; }
...etc...
}
These service classes all contains a RepositoryManager that has been injected, and since they're all in ScreenViewModel the ISession object will be the same, at least in my WPF build. if I switch to my MVC build they're the same for all view models created for a given request, and if I switch to a console build it uses the same ISession for everything in the entire program.
TL;DR: Use dependency injection and a scope your contexts to one-per-form.

In my earlier usage of MVVM within WPF I was utilising an open context per VM but I quickly ran into issues with thread safety of DBContexts once applications evolved to make better use of Async.
Whilst there is a greater development overhead, I now utilise dependency injection to provide a DBContextFactory (not the DBContext itself). I spin up a context in a using statement witihn the VM to fill observableCollections with plinq calls via EF. Another performance benefit of this method is running queries with AsNoTracking(). The annoying part is managing the reattachment of new or modified objects to the short lived context:
shortDBContext.Attach(myEntity).State = EntityState.Added; // or modified
await shortDBContext.SaveChangesAsync();

Related

Dependency Injection for singelton class with properties

I am having a custom context class in my ASP.NET 4.8 Framework website:
public sealed class MyCustomContext
{
private static readonly Lazy<MyCustomContext> staticContext =
new Lazy<MyCustomContext>(() => new MyCustomContext());
private MyCustomContext()
{
}
public static MyCustomContext Current => staticContext.Value;
public HttpContext Context => HttpContext.Current;
// Logic to return current user based on logged in user
public User LoggedInUser => ...
// Logic to return SiteWideSettings
public Collection<SiteWideSettings> SiteWideSettings => ...
}
The above class is a Singleton and the usage of the above class in my service class methods is like this:
public class MyService : IMyService
{
public MyService()
{
}
public void DoWork()
{
var current = MyCustomContext.Current;
var loggedInUser = current.LoggedInUser;
var siteWideSettings = current.SiteWideSettings;
var currentContext = current.Context;
// use the above properties further for this method
}
}
My goal is to remove MyCustomContext class dependency hardcoded in my DoWork method of MyService class so that it can look like this:
public class MyService : IMyService
{
private readonly IMyCustomContext _myCustomContext;
public MyService(IMyCustomContext myCustomContext)
{
_myCustomContext = myCustomContext;
}
public void DoWork()
{
var current = _myCustomContext.Current;
var loggedInUser = current.LoggedInUser;
var siteWideSettings = current.SiteWideSettings;
var currentContext = current.Context;
// use the above properties further for this method
}
}
Can you share how to convert my MyCustomContext class so that it can be injected via dependency injection into MyService?
I have one more question, do the properties like LoggedInUser, SiteWideSettings and Context of MyCustomContext class should be written as properties or they should be converted to methods for dependency injection?
For the dependency injection you need an interface which gets initialized, so your MyCustomContext class needs to implement a new interface called IMyCustomContext. The interface can look like following:
public interface IMyCustomContext
{
HttpContext Context { get; }
User LoggedInUser { get; }
Collection<SiteWideSettings> SiteWideSettings { get; }
}
public class MyCustomContext : IMyCustomContext
{
public HttpContext Context
{
get { return HttpContext.Current; }
}
public User LoggedInUser
{
get
{
// Logic to return current user based on logged in user
}
}
public Collection<SiteWideSettings> SiteWideSettings
{
get
{
// Logic to return SiteWideSettings
}
}
}
In the Startup.cs there is a method called ConfigureServices, there you can add the following for the dependency injection:
container.RegisterType<IMyCustomContext, MyCustomContext>(
TypeLifetime.Singleton);
It's worth pointing out that Singleton has dual meaning here:
The Singleton Design Pattern ensures an object is only instantiated once. Its implementation isn't ideal though, as it relies on ambient state.
The Singleton Lifetime is used by IOC frameworks, where it ensures the same reference of an object is used every time.
In short, the Singleton Lifetime effectively removes the need to implement the Design Pattern, because the IOC framework ensures the backing concept for you.
Meaning, if we register our dependency with the Singleton Lifetime.
container.RegisterType<ICustomContext, MyCustomContext>(TypeLifetime.Singleton);
We can remove the code for the Singleton Pattern, as the IOC container will take over the responsibility of guarding the single instance/reference.
public class MyCustomContext : ICustomContext
{
public HttpContext Context => HttpContext.Current;
// Logic to return current user based on logged in user
public User LoggedInUser => ...
// Logic to return SiteWideSettings
public Collection<SiteWideSettings> SiteWideSettings => ...
}
I've also added the ICustomContext interface with the member we're interested in.
public interface ICustomContext
{
HttpContext Context { get; }
User LoggedInUser { get; }
Collection<SiteWideSettings> SiteWideSettings { get; }
}
Can you share how to moq properties of that class?
That's right, we just moved the problem one level, didn't we? If you need to extract an interface, you usually need to do this in a recursive manner.
This also means HttpContext is not a good candidate for an interface member, which makes sense when you think about it. From a unit test's point of view, we're not interested in verifying ASP.NET's inner workings. Instead, we want to check our own code, and only that portion, with no dependencies on foreign libraries. To do so, you should only copy the HttpContext members you need on to your interface and remove the dependency on HttpContext (which is notoriously hard to abstract).
For example:
public interface ICustomContext
{
IPrincipal User { get; }
User LoggedInUser { get; }
Collection<SiteWideSettings> SiteWideSettings { get; }
}
This will require some refactoring / remodeling as the number of properties grows.
For simple DTO's you can even choose not to abstract / interface them, as long as your able to easily create fakes for unit testing. Also remember it only makes sense to introduce an interface if there are going to be multiple implementations.
One more thing about Dependency Inversion, and how IOC frameworks work, you usually let the dependencies bubble up. The recommended approach is through constructor injection, as illustrated in the following ICustomContext implementation for unit tests.
public class TestCustomContext : ICustomContext
{
public MyCustomContext(IPrincipal user, User loggedInUser, Collection<SiteWideSettings> siteWideSettings)
{
User = user;
LoggedInUser = loggedInUser;
SiteWideSettings = siteWideSettings;
}
IPrincipal User { get; }
User LoggedInUser { get; }
Collection<SiteWideSettings> SiteWideSettings { get; }
}
I have one more question, do the properties like LoggedInUser, SiteWideSettings and Context of MyCustomContext class should be written as properties or they should be converted to methods for dependency injection?
You can have both. If the state was injected through constructor injection, you might as well expose it as a property. If the implementing class implements behavior to create / transform the state, you might want to expose the behavior as a method. It all depends on the actual case, there is no golden bullet here. Just remember that in OO design, interfaces are used to model behaviors, with their scope kept as small as possible.
UPDATE
Those properties are not getting filled via constructor. All of these properties "IPrincipal User { get; } User LoggedInUser { get; } Collection SiteWideSettings { get; }" have the body in their getter, they get the data from cache first and if not found then it calls the service to get the data from db for those properties (all that is written in in the get of those properties). Should I keep them as properties only or make them methods?
Let me split up your question.
Should I keep them as properties only or make them methods?
From a technical point of view, it doesn't really matter. Properties, or automated properties (like the ones you're using), are just syntactic sugar over full blown methods. Meaning, they all get compiled into equivalent CIL instructions.
That leaves only the human factor. The readability and maintainability of your code. The agreed upon coding style and practices. That's not something I can answer for you. Personally, I prefer methods for handling these kind of code flows.
they get the data from cache first and if not found then it calls the service to get the data from db for those properties (all that is written in in the get of those properties).
Sounds like this class is more of a service provider than an actual model class in your domain. As there's also I/O involved, I'd definitely recommend switching to asynchronous methods on your interface. The explicit (Task based) signature says a lot to fellow developers reading your code.
The part where I talked about the dependencies bubbling up plays an important role here. The cache and repository are both dependencies of MyCustomContext. IOC and its inherent Dependency Inversion Principle rely on the explicit declaration of dependencies, as shown in the following sample. Note the implementation of GetLoggedInUser() is not what matters here, rather the way the dependencies are set through the constructor. All these dependencies need to be registered with your IOC container first, for it to be able to resolve ICustomContext.
public class MyCustomContext : ICustomContext
{
private readonly IUsersCache _usersCache;
private readonly IUsersRepo _usersRepo;
public MyCustomContext(IUsersCache usersCache, IUsersRepo usersRepo, IPrincipal principal)
{
_usersCache = usersCache;
_usersRepo = usersRepo;
Principal = principal;
}
public IPrincipal Principal { get; }
public async Task<LoggedInUser> GetLoggedInUser()
{
var userId = await GetUserId(Principal);
var user = _usersCache.GetById(userId);
if (user == null)
{
user = _usersRepo.GetById(userId);
_usersCache.Add(user);
}
return user;
}
...
}
Those properties are not getting filled via constructor. All of these properties "IPrincipal User { get; } User LoggedInUser { get; } Collection SiteWideSettings { get; }" have the body in their getter
I don't think that's true for IPrincipal as it, together with HttpContext, is instantiated by ASP.NET behind the scenes. All you need to do is tell the IOC container how to resolve the current IPrincipal and let it work its magic.
Likewise, all classes that depend on ICustomContext should have it injected by the IOC container.
public class MyService : IMyService
{
private readonly ICustomContext _customContext;
public MyService(ICustomContext customContext)
{
_customContext = customContext;
}
public async Task DoWork()
{
var currentPrincipal = _customContext.Principal;
var loggedInUser = await _customContext.GetLoggedInUser();
...
}
}
An important part here is again unit testing. If you design your classes like this, you can easily create fakes for testing. And even if there wasn't any testing involved, which I wouldn't recommend, the ability to decouple classes like this is a good indication of a well designed code base.

Repository Pattern and Unity Container.. create object in controller for entity/POCO

Working on web api using EF codefirst approach.
I want to use Dependency injection using Unity framework.
i downloaded--Unity.webapi, it addeds few unity files(unityconfig, unityresolver). my entities i registered as like attachment.
but my codefirst entities not implements any interfaces, all are plain code first classes. now i want to write code in my controllers. how to write ?
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<ApplicationDbContext,PolicyInfo>));
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<ApplicationDbContext, LossInformation>));
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<ApplicationDbContext, Manufacturer>));
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<ApplicationDbContext, ModelVariant>));
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
class
public class **PolicyInfo**
{
[Key]
public int PolicyId { get; set; }
[Required]
public string Manufacturer { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime PolicyIssuedDate { get; set; }
}
controller:
[RoutePrefix("api/PolicyInfo")]
public class PolicyInfoController : ApiController
{
GenericRepository<ApplicationDbContext, PolicyInfo> policycontext;
public PolicyInfoController()
{
this.policycontext = new GenericRepository<ApplicationDbContext, PolicyInfo>();
}
}
I hope this is not write way to create context object. because i written PolicyInfo object at constructor level. please suggest any one.
One of the key concepts behind Inversion of Control (IoC) and Dependency Injection (DI) is precisely not to have to manually instantiate the required dependencies inside the consumer class but those dependencies to get injected into the class.
So if you are using Unity or any other framework, the goal is to suppress the line where you are creating the object context by a parameter in this case in the constructor of your API Controller.
So you if your IoC container is properly configured you should be able to get a reference to the GenericRepository using e.g, constructor injection:
Try this:
[RoutePrefix("api/PolicyInfo")]
public class PolicyInfoController : ApiController
{
IGenericRepository<ApplicationDbContext, PolicyInfo> policycontext;
public PolicyInfoController(IGenericRepository<ApplicationContext,PolicyInfo> policyContext)
{
//use the context here... e.g.: Save the reference to the instance field.
this.policyContext = policyContext;
}
}
However, I would suggest a bit more of abstraction in your code in order to make it clearer and more efficient.
Take a look a this article, although a little old, still applies perfectly to your problem. Hope this helps.

How to write unit tests for proxy pattern?

Will be thankful for your attention, time and efforts !
I have the following code
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Role { get; set; }
}
public interface IEmployeeRepository
{
Employee GetEmployee(string firstName, string role);
}
public class EmployeeRepository : IEmployeeRepository
{
public Employee GetEmployee(string firstName, string role)
{
//logic here
return new Employee();
}
}
Now i want to implement cache for EmployeeRepository.
At first i did it using Proxy design pattern
public class ProxyEmployeeRepository : IEmployeeRepository
{
private EmployeeRepository _employeeRepository = new EmployeeRepository();
private MemoryCache _cache = new MemoryCache("UsualCache");
public Employee GetEmployee(string firstName, string role)
{
//do not cache administrators
if (role == "admin")
{
return _employeeRepository.GetEmployee(firstName, role);
}
else
{
//get from cache at first
//if absent call _employeeRepository.GetEmployee and add to cache
//...
}
}
But when wanted to write unit tests for this class i couldn't do it(i cannot create mock for _employeeRepository and verify whether it was called or not)
If i implement cache with Decorator pattern then i would have the following code
public class DecoratorEmployeeRepository : IEmployeeRepository
{
private IEmployeeRepository _employeeRepository;
public DecoratorEmployeeRepository(IEmployeeRepository repository)
{
_employeeRepository = repository;
}
private MemoryCache _cache = new MemoryCache("UsualCache");
public Employee GetEmployee(string firstName, string role)
{
//do not cache administrators
if (role == "admin")
{
return _employeeRepository.GetEmployee(firstName, role);
}
else
{
//get from cache at first
//if absent call _employeeRepository.GetEmployee and add to cache
return null;
}
}
}
and unit tests for it
[TestClass]
public class EmployeeRepositoryTests
{
[TestMethod]
public void GetEmployeeTest_AdminRole()
{
var innerMock = Substitute.For<IEmployeeRepository>();
var employeeRepository = new DecoratorEmployeeRepository(innerMock);
employeeRepository.GetEmployee("Ihor", "admin");
innerMock.Received().GetEmployee(Arg.Any<string>(), Arg.Any<string>());
}
[TestMethod]
public void GetEmployeeTest_NotAdminRole()
{
var innerMock = Substitute.For<IEmployeeRepository>();
var employeeRepository = new DecoratorEmployeeRepository(innerMock);
employeeRepository.GetEmployee("Ihor", "NotAdmin");
innerMock.DidNotReceive().GetEmployee("Ihor", "NotAdmin");
}
}
Is it possible to write unit tests for first approach with proxy pattern ? i just don't understand how it is possible to cover proxy class with unit tests ...
I know it is too late to answer your question but it might help other new visitors:
I think your problem is your misunderstanding of both patterns. By using composition instead of instantiating your class inside the proxy, does not necessarily mean that you have changed your pattern from proxy to decorator. Each of these patterns is solving a specific problem. Let me clarify each:
Decorator Pattern:
This pattern is useful when you have different kinds of behaviours in your main class (like caching, logging, lazy loading and etc.) and you want to use each of these or a combination of them in different places of your application. For example, in your controller, you need only caching, in the admin controller you don't need caching but logging and in another service, you need both plus lazy loading. Therefore you will create three decorators for each extra behaviour (caching, logging and lazy loading) and in each place, you link the decorators into each other to provide various kinds of behaviours. The benefit of this pattern is that each class has only one responsibility. Additionally, your application is open to extension and close to modification. If you need a new behaviour, you can simply implement a new decorator from the interface and add it only to the services or controllers that the new behaviour is required without modifying the current implementation.
Proxy Pattern:
This pattern is useful when you want to add specific behaviour or behaviours that are required for your class but can prevent the actual behaviour (querying the database) and/or new behaviours come into the picture (which is not the behaviour in the decorator pattern. It only enhances the main behaviour). Another usage of this pattern is when instantiating the main class is costly. So in contrast, you do not need each behaviour (or various combination of them) separately in several places of your application.
The benefit of this pattern is that it prevents adding several responsibilities to your main class. Besides, it is still close to modification and open to extension. If the requirements change in future, you can simply implement a new proxy and replace it with the correct one or use it separately.
The answer to your question:
Therefore, as I mentioned above, by having a composition to your interface instead of instantiating it directly, you are not changing the pattern. In proxy pattern, the main class can be injected via the interface or the concrete implementation as well.

reusing services calls in unit of work pattern

I have a scenario using WebApi, Generic Repository, EF6 and unit of work pattern
(in order to wrap all changes from several calls to the same context.)
Manager layer is used to perform calls to different repositories and also to other managers.
Currently Customer Manager does inject both repos and other Managers like:
public class CustomerManager {
public CustomerManager(IRepository<Customer> _customerRepository, IRepository<Order> orderRepository, IManager itemManager) {
_orderReporsitory = orderReporsitory;
_itemManager = itemManager;
_customerRepository = customerRepository;
}
public bool Save(Customer customer) {
_orderReporsitory.Find...
_itemManager.IsItemUnique(ItemId)
_customerRepository.Save(customer);
}
}
This code does not compile, for reference only.
Approaches like this
http://blog.longle.net/2013/05/11/genericizing-the-unit-of-work-pattern-repository-pattern-with-entity-framework-in-mvc/
Will wrap several repositories under a unit of work and flush the changes all together.
My issue involves also adding another Manager layer, to be wrapped also inside unit of work and allow both calls to repositories and other managers
(as I want to reuse some manager logic. Like in the example, I am re-using some ItemManager logic)
This code https://stackoverflow.com/a/15527444/310107
using (var uow = new UnitOfWork<CompanyContext>())
{
var catService = new Services.CategoryService(uow);
var custService = new Services.CustomerService(uow);
var cat = new Model.Category { Name = catName };
catService.Add(dep);
custService.Add(new Model.Customer { Name = custName, Category = cat });
uow.Save();
}
is using something similar of what I need but I would also like to be able to inject the services to unit test them (and not creating instances in the body of my manager/service method)
What would the best approach to do this ?
Thanks
Your code snippet with the unit of work has several problems, such as:
You create and dispose the unit of work explicitly within that method, forcing you to pass along that unit of work from method to method and class to class.
This causes you to violate the Dependency Inversion Principle, because you now depend on concrete types (CategoryService and CustomerService), which complicates your code and makes your code harder to test.
If you need to change the way the unit of work is created, managed or disposed, you will have to make sweeping changes throughout the application; A violation of the Open/Closed Principle.
I expressed these problems in more details in this answer.
Instead, I propose to have one DbContext, share it through a complete request, and control its lifetime in the application's infrastructure, instead of explicitly throughout the code base.
A very effective way of doing this is by placing your service layer behind a generic abstaction. Although the name of this abstraction is irrelevant, I usually call this abstraction 'command handler:
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
There are a few interesting things about this abstaction:
The abstraction describes one service operation or use case.
Any arguments the operation might have are wrapped in a single message (the command).
Each operation gets its own unique command class.
Your CustomerManager for instance, might look as follows:
[Permission(Permissions.ManageCustomerDetails)]
public class UpdateCustomerDetailsCommand {
public Guid CustomerId { get; set; }
[Required] public string FirstName { get; set; }
[Required] public string LastName { get; set; }
[ValidBirthDate] public DateTime DateOfBirth { get; set; }
}
public class UpdateCustomerDetailsCommandHandler
: ICommandHandler<UpdateCustomerDetailsCommand> {
public UpdateCustomerDetailsCommandHandler(
IRepository<Customer> _customerRepository,
IRepository<Order> orderRepository,
IManager itemManager) {
_orderReporsitory = orderReporsitory;
_itemManager = itemManager;
_customerRepository = customerRepository;
}
public void Handle(UpdateCustomerDetailsCommand command) {
var customer = _customerRepository.GetById(command.CustomerId);
customer.FirstName = command.FirstName;
customer.LastName = command.LastName;
customer.DateOfBirth = command.DateOfBirth;
}
}
This might look like just a bunch of extra code, but having this message and this generic abstraction allows us to easily apply cross-cutting concerns, such as handling the unit of work for instance:
public class CommitUnitOfWorkCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> {
private readonly IUnitOfWork unitOfWork;
private readonly ICommandHandler<TCommand> decoratee;
public CommitUnitOfWorkCommandHandlerDecorator(
IUnitOfWork unitOfWork,
ICommandHandler<TCommand> decoratee) {
this.unitOfWork = unitOfWork;
this.decoratee = decoratee;
}
public void Handle(TCommand command) {
this.decoratee.Handle(command);
this.unitOfWork.SaveChanges();
}
}
The class above is a decorator: It both implements ICommandHandler<TCommand> and it wraps ICommandHandler<TCommand>. This allows you to wrap an instance of this decorator around each command handler implementation and allow the system to transparently save the changes made in the unit of work, without any piece of code having to do this explicitly.
It is also possible to create a new unit of work here, but the easiest thing to start with is to let the unit of work live for the duration of the (web) request.
This decorator will however just be the beginning of what you can do with decorators. For instance, it will be trivial to:
Apply security checks
Do user input validation
Run the operation in a transaction
Apply a deadlock retry mechanism.
Prevent reposts by doing deduplication.
Register each operation in an audit trail.
Store commands for queuing or background processing.
More information can be found in the articles, here, here and here.

How to scope out Dbcontexts (to prevent singleton context for entire application)

I was wondering how do you scope out your Dbcontexts in Entity Framework so you don't use a single Dbcontext for your entire application. I am new to Entity Framework and have been reading tutorials, but they all used a single Dbcontext as an example, so EF is pretty much a blackbox for me right now.
Let's say for example I have 3 models:
Post
User
Comment
Each model is related to each other (A Post belongs to User, Comment belongs to User and Post). Do I make a Dbcontext for each one individually? But that wouldn't be correct since they are all related, or would I make a Dbcontext for each scenario that I need? For example, if I only need to query for Post and Comments and not user, that would be a PostCommentsContext. And then we would have a PostUserCommentContext...
The best solution would be to use a Unit of Work to wrap the Data Context, as well as managing the connection lifetime and allowing you to work with multiple Repositories (if you were so inclined to go down that path).
Summary of implementation:
Create an interface (IUnitOfWork) which exposes properties for your DbSet's, as well as a single method called Commit
Create an implementation (EntityFrameworkUnitOfWork), implementing as required. Commit simply calls SaveChanges on the base class (DbContext), and also provides a good hook-in for last minute logic.
Your controller accepts a IUnitOfWork, use DI (preferably) to resolve a EntityFrameworkUnitOfWork, with a HTTP-context scoped lifetime setting (StructureMap is good for this)
(optional, but recommended) create a Repository which also takes the IUnitOfWork, and work off that via your Controller.
HTH
EDIT - In Response to Comments
Oh, how can you do work that involves creating records in multiple models then? i.e., create a new user and a new post in the same transaction.
Given your using ASP.NET MVC, your controllers should accept an IUnitOfWork in their constructor.
Here's an example, based on what you asked
public SomeController : Controller
{
private IUnitOfWork _unitOfWork;
private IUserRepo _userRepo;
private IPostRepo _postRepo;
public SomeController(IUnitOfWork unitOfWork, IUserRepo userRepo, IPostRepo postRepo)
{
_unitOfWork = unitOfWork; // use DI to resolve EntityFrameworkUnitOfWork
_userRepo = userRepo;
_postRepo = postRepo;
}
[HttpPost]
public ActionResult CreateUserAndPost(User user, Post post)
{
// at this stage, a HTTP request has come in, been resolved to be this Controller
// your DI container would then see this Controller needs a IUnitOfWork, as well
// as two Repositories. DI smarts will resolve each dependency.
// The end result is a single DataContext (wrapped by UoW) shared by all Repos.
try
{
userRepo.Add(user);
postRepo.Add(post);
// nothing has been sent to DB yet, only two objects in EF graph set to EntityState.Added
_unitOfWork.Commit(); // two INSERT's pushed to DB
}
catch (Exception exc)
{
ModelState.AddError("UhOh", exc.ToString());
}
}
}
And one more question, what does the HTTP-context scoped lifetime do?
Objects in DI-talk have scope management settings that include per thread, per session, per http request, singleton, etc.
HTTP-context scoped is the recommended setting for web apps. It means "new up a context when a HTTP request comes in, and get rid of it when the request is finished".
Use 1 DbContext! That will make life easier for you. Don't worry about performance, data that isn't needed or queried won't be loaded and won't consume any resources.
public class UserContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> Comments { get; set; }
}
For some scenarios you might want 2 or more contexts.
A context like the one above to hold all the front-end data needed for your application to work and another context for - as an example - to store reports generated from that front-end data, and which is only used in the back-end of you application.
I am experimenting with UnitofWork, here is what I have come up with...
First I created a IUnitofWork that only contains one method. Commit();
Then my dbContext looks like this
public class myContext : DbContext, IUnitOfWork
{
public DbSet<Users> Users { get; set; }
public DbSet<Addresses> Address { get; set; }
public void Save()
{
SaveChanges();
}
}
My repository classes take a UnitofWork in their ctors.
public class UserRepository : IRepository<Position>
{
private myContext _context;
public UserRepository (IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
_context = unitOfWork as myContext;
}
/// other methods ///
}
Then the code in the controller would be something like this
_unitOfWork = new myContext();
_userDB = new UserRepository(_unitOfWork);
_addressDB = new AddressRepository(_unitOfWork);
_userDB.Add(newUser);
_addresesDB.Add(newAddress);
_unitOfWork.Save();
I have debugged and proved that no data is commited until the Save method of the _unitOfWork is called. Very cool stuff!!

Categories

Resources