After googling a while I would like to know which is best pratices for DBContext (EntityFramework or Linq-to-Sql).
In practise I would lie to know which one of the following "patterns" has less cons:
1) Get Code From Here
public class ContextFactory
{
[ThreadStatic]
private static DBDataContext context;
//Get connectionString from web.config
private static readonly string connString = ConfigurationManager.ConnectionStrings["ConnectionString1"].ConnectionString;
public static DBDataContext Context()
{
if (context == null)
context = new DBDataContext(connString);
return context;
}
public static void FlushContext()
{
context = new DBSkillDataContext(connString);
}
}
In this way i use FlushContext each time Controller is initialized.
2) In this way (get code from Here)
public class UnitOfWork : IUnitOfWork, IDisposable
{
DBContext context= null;
IUserRepository userRepo = null;
IAccountRepository accountRepo = null;
public UnitOfWork()
{
context= new DBContext();
userRepo= new UserRepository(context);
accountRepo= new accountRepo(context);
}
public IUserRepository userRepo
{
get
{
return userRepo;
}
}
public IAccountRepository accountRepo
{
get
{
return accountRepo;
}
}
public void Dispose()
{
// If this function is being called the user wants to release the
// resources. lets call the Dispose which will do this for us.
Dispose(true);
// Now since we have done the cleanup already there is nothing left
// for the Finalizer to do. So lets tell the GC not to call it later.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing == true)
{
//someone want the deterministic release of all resources
//Let us release all the managed resources
context= null;
}
}
~UnitOfWork()
{
// The object went out of scope and finalized is called
// Lets call dispose in to release unmanaged resources
// the managed resources will anyways be released when GC
// runs the next time.
Dispose(false);
}
}
public abstract class AController : Controller
{
private IUnitOfWork IUnitOfWork;
protected IUnitOfWork UnitOfWork_
{
get { return IUnitOfWork; }
}
public AController(IUnitOfWork uow)
{
this.IUnitOfWork = uow;
}
}
public class UserController : AController
{
// use our DbContext unit of work in case the page runs
public UserController()
: this(new UnitOfWork())
{
}
// We will directly call this from the test projects
public UserController(UnitOfWork unitOfWork)
: base (unitOfWork)
{
}
public ActionResult Index()
{
List<User> users= UnitOfWork_.usersRepo.GetUsers();
return View(users);
}
}
So what I'm asking is, which one of the above is best practice to use?
Don't make DbContext static. DbContext is not thread safe and making it static makes it easy to use from multiple threads - especially in we scenarios which may lead to hard to debug/resolve bugs and maybe even data corruption. In additon keeping context alive for extended periods of time is not a good idea - it will track more and more entities and therefore will gradually get slower and slower. It will also prevent GC from collecting objects that are being tracked but are not used.
The other example is much better. DbContext itself is kind of UnitOfWork. I am not sure if I would start with the Reposiory pattern here. I would rather use the DbContext directly and move to using patterns when they emerge from my code and only if there is a benefit from using the pattern (note that patterns require more code that needs to be understood and maintained).
Related
I have created my data provider using Repository Pattern.
First, I designed a base repository interface as following:
internal interface IGenericRepository<T, in TResourceIdentifier>
{
Task<IEnumerable<T>> GetManyAsync();
Task<T> GetAsync(TResourceIdentifier id);
Task PutAsync(T model);
Task<T> PostAsync(T model);
Task DeleteAsync(TResourceIdentifier id);
}
Then I implemented it:
public class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier>
where T : class
{
private bool _disposed;
protected HttpClientHelper<T, TResourceIdentifier> Client;
protected GenericRepository(string addressSuffix)
{
Client = new HttpClientHelper<T, TResourceIdentifier>(Properties.Settings.Url, addressSuffix);
}
public async Task<IEnumerable<T>> GetManyAsync()
{
return await Client.GetManyAsync();
}
// All other CRUD methods and dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(_disposed || !disposing) return;
if(Client != null)
{
var mc = Client;
Client = null;
mc.Dispose();
}
_disposed = true;
}
}
Then I created custom repository interface for each of my entities. For example:
internal interface IOrderRepository : IGenericRepository<Order, int>
{
Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition );
}
And finally, I implemented the custom repository:
public class OrderRepository : GenericRepository<Order, int>, IOrderRepository
{
public OrderRepository(string addressSuffix) : base(addressSuffix)
{
}
public async Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition)
{
//get all the orders (GetManyAsync()) and then returns the ones meeting the condition
}
}
Note that HttpClientHelperuses HttpClient and needs to be disposed manually.
I have created a MVC web application and have defined the repositories at the class level as such:
IOrderRepository _orderRepository = new OrderRepository();
When I call _orderRepository in my CRUD operations, it does not hit dispose after its use. In order to fix that I have ended up implementing like this:
private async Task<IEnumerable<OrderViewModel>> GetOrders()
{
using(var orderRepository = new OrderRepository())
return await orderRepository.GetManyAsync();
}
This would hit the Dispose but is anti pattern.
What am I missing in my implementation that the instance is not disposed on each call?
You should not be disposing HTTPClient after every request.
[https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests][1]
As the above link says -
Therefore, HttpClient is intended to be instantiated once and reused
throughout the life of an application. Instantiating an HttpClient
class for every request will exhaust the number of sockets available
under heavy loads. That issue will result in SocketException errors.
Possible approaches to solve that problem are based on the creation of
the HttpClient object as singleton or static, as explained in this
Microsoft article on HttpClient usage.
Writing a Dispose method in your generic repository does not mean it will be invoked automatically, whenever you feel like it should. It's intended to be invoked individually, hence why you must either use a using statement (as you have shown), or the Dispose method inside your code.
Alternatively, you can leave that job for the garbage collector.
You should also create a finalizer in your generic repository, if you're convinced on using GC.SuppressFinalize(this);
Read more about that here - When should I use GC.SuppressFinalize()?
As R Jain pointed out, you should also create a static class to hold your HttpClient. You'll have to use HttpResponseMessages for your needs, or HttpContent.
Some more resources to read:
HttpClient single instance with different authentication headers
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
A sample of uow:
using System;
using ContosoUniversity.Models;
namespace ContosoUniversity.DAL
{
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
public GenericRepository<Course> CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new GenericRepository<Course>(context);
}
return courseRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
As you see uow includes dispose method and inside it disposes dbContex object. Why should we explicitly dispose the dbContext object. Since it is a member of uow, outside the scope it will disposed by garbace collector automaticly. So, why are we doing this manually? As an example:
using(Uow uowObject = new Uow())
{
//there is a dbcontext
}
//it will be disposed automaticly by gc
Outside the scope the variable is no longer reachable but that doesn't mean disposed. As a rule of thumb, every class that implements IDisposable should be disposed. In the case of EF, it will clear the cache, the graph that tracks object changes and rollback any uncommitted transactions as well.
With GC, you don't know when GC will be started. Even the variable is out of scope, it doesn't mean it has been garbage collected. With dispose pattern, you can free the memory right away.
From MSDN :In determining when to schedule garbage collection, the runtime takes into account how much managed memory is allocated. If a small managed object allocates a large amount of unmanaged memory, the runtime takes into account only the managed memory, and thus underestimates the urgency of scheduling garbage collection.
So for the managed objects which hold native resource, you should call dispose to free the native resource.
I have a CommandHandler that implements some logic for an object and commits context (in my case RavenDb IDocumentSession). I need to implement the same logic for a collection of objects. The first idea is to create a new CommandHandler which would call the first CommandHandler for each object in the foreach. But it would result in N database roundtrips.
The best idea I came to was to create a base CommandHandler with the logic itself but without context commit. Something like this:
internal class AuditProductCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductCommand>
{
private readonly IDocumentSession _documentSession;
public AuditProductCommandHandler(IDocumentSession documentSession)
{
_documentSession = documentSession;
}
public void Execute(AuditProductCommand command)
{
AuditProduct(command.Product);
_documentSession.SaveChanges();
}
}
internal class AuditProductsCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductsCommand>
{
private readonly IDocumentSession _documentSession;
public AuditProductsCommandHandler(IDocumentSession documentSession)
{
_documentSession = documentSession;
}
public void Execute(AuditProductsCommand command)
{
foreach (var product in command.Products)
{
AuditProduct(product);
}
_documentSession.SaveChanges();
}
}
internal class AuditProductCommandHandlerBase
{
protected void AuditProduct(Product product)
{
//logic itself
}
}
For some reason I feel uncomfortable about this solution. Are there any better options?
I would propose to remove _documentSession.SaveChanges() altogether from the command handler implementation and move the responsibility to the caller. The caller can then decide if they have to chain multiple command handlers or multiple DB operations and then call the SaveChanges() after that. Since caller is responsible for creating/sending the IDocumentSession object, they can take the responsibility of saving and disposing of it too.
Basically, is there an easy way to dispose of the imports that are created by an ExportFactory<T>? The reason I ask is because the exports usually contain a reference to something that is still around, such as the EventAggregator. I don't want to run into the issue where I'm creating hundreds of these and leaving them laying around when they are not necessary.
I noticed that when I create the objects I get back a ExportLifetimeContext<T> which carries a Dispose with it. But, I don't want to pass back an ExportLifetimeContext to my ViewModels requesting copies of the ViewModel, hence I pass back the Value. (return Factory.Single(v => v.Metadata.Name.Equals(name)).CreateExport().Value;)
When you call Dispose on an ExportLifetimeContext<T> it will call dispose on any NonShared part involved in the creation of T. It won't dispose of any Shared components. This is a safe behaviour, because if the NonShared parts were instantiated purely to satisfy the imports for T, then they can safely be disposed as they won't be used by any other imports.
The only other way I think you could achieve it, would be to customise the Dispose method to chain the dispose call to any other member properties you import with, e.g.:
[Export(typeof(IFoo))]
public class Foo : IFoo, IDisposable
{
[Import]
public IBar Bar { get; set; }
public void Dispose()
{
var barDisposable = Bar as IDisposable;
if (barDisposable != null)
barDisposable.Dispose();
}
}
But as your type has no visibility of whether the imported instance of IBar is Shared or NonShared you run the risk of disposing of shared components.
I think hanging onto the instance of ExportedLifetimeContext<T> is the only safe way of achieving what you want.
Not sure if this helps, feels like unnecessary wrapping, but could you possibly:
public class ExportWrapper<T> : IDisposable
{
private readonly ExportLifetimeContext<T> context;
public ExportWrapper<T>(ExportLifetimeContext<T> context)
{
this.context = context;
}
public T Value
{
get { return context.Value; }
}
public void Dispose()
{
context.Dispose();
}
public static implicit operator T(ExportWrapper<T> wrapper)
{
return wrapper.Value;
}
public static implicit operator ExportWrapper<T>(ExportLifetimeContext<T> context)
{
return new ExportWrapper<T>(context);
}
}
Which you could possibly:
[Import(typeof(IBar))]
public ExportFactory<IBar> BarFactory { get; set; }
public void DoSomethingWithBar()
{
using (ExportWrapper<IBar> wrapper = BarFactory.CreateExport())
{
IBar value = wrapper;
// Do something with IBar;
// IBar and NonShared imports will be disposed of after this call finishes.
}
}
Feels a bit dirty...
So I'm working on my DI/IoC Container OpenNETCF.IoC and I've got a (reasonable) feature request to add some form of lifecycle management for IDisposable items in the container collections.
My current thinking is that, since I can't query an object to see if it's been disposed, and I can't get an event for when it's been disposed, that I have to create some form of wrapper for objects that a developer wants the framework to manage.
Right now objects can be added with AddNew (for simplicity sake we'll assume there's only one overload and there is no Add):
public TTypeToBuild AddNew<TTypeToBuild>() { ... }
What I'm considering is adding a new method (well group of them, but you get the picture):
public DisposableWrappedObject<IDisposable> AddNewDisposable<TTypeToBuild>()
where TTypeToBuild : class, IDisposable
{
...
}
Where the DisposableWrappedObject looks like this:
public class DisposableWrappedObject<T>
where T : class, IDisposable
{
public bool Disposed { get; private set; }
public T Instance { get; private set; }
internal event EventHandler<GenericEventArgs<IDisposable>> Disposing;
internal DisposableWrappedObject(T disposableObject)
{
if (disposableObject == null) throw new ArgumentNullException();
Instance = disposableObject;
}
~DisposableWrappedObject()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
lock(this)
{
if(Disposed) return;
EventHandler<GenericEventArgs<IDisposable>> handler = Disposing;
if(handler != null)
{
Disposing(this, new GenericEventArgs<IDisposable>(Instance));
}
Instance.Dispose();
Disposed = true;
}
}
}
Now, when an items gets added to the container via AddNewDIsposable, an eventhandler is also added so that when it gets Disposed (via the wrapper) the framework removes it from the underlying collection.
I actually have this implemented and it's passing the unit tests, but I'm looking for opinions on where this might be broken, or how it might be made more "friendly" to the consuming developer.
EDIT 1
Since there was a question on how the Disposing event is used, here's some code (trimmed to what's important):
private object AddNew(Type typeToBuild, string id, bool wrapDisposables)
{
....
object instance = ObjectFactory.CreateObject(typeToBuild, m_root);
if ((wrapDisposables) && (instance is IDisposable))
{
DisposableWrappedObject<IDisposable> dispInstance = new
DisposableWrappedObject<IDisposable>(instance as IDisposable);
dispInstance.Disposing += new
EventHandler<GenericEventArgs<IDisposable>>(DisposableItemHandler);
Add(dispInstance as TItem, id, expectNullId);
instance = dispInstance;
}
....
return instance;
}
private void DisposableItemHandler(object sender, GenericEventArgs<IDisposable> e)
{
var key = m_items.FirstOrDefault(i => i.Value == sender).Key;
if(key == null) return;
m_items.Remove(key);
}
Maybe I'm missing something, but why add new methods to the API? When an object is added to the container, you could as-cast to check if it's IDisposable and handle it appropriately if so.
I'm also wondering if you need the destructor. Presuming the container is IDisposable (like Unity's), you could just implement the Basic Dispose Pattern and save a lot of GC overhead.
Some questions that may be applicable:
How do you reconcile IDisposable and IoC?
Can inversion of control and RAII play together?