I am performing a work unit. This is part of my interface:
public interface IUnitOfWork { void Add(object entity); void Update(object entity); void Delete(object entity); void Commit(); }
It seems that from the examples that I found on the Internet or in books, the work unit is forced to work with the type “object”, since we can add any “type” of the object to uow.
It doesn't matter until Commit () comes. When I commit, given the type of entity, I need to find the repository based on the type of entity, and then call the appropriate action.
For example, I have an object type called Expert
public class Expert { public object ID { get; set; } public string Name { get; set; } }
An expert has a repository named ExpertRepository. All repositories in my application implement IRepository:
public interface IRepository<T> { void Create(T item); void Update(T item); void Delete(T item); } public class ExpertRepository : IRepository<Expert> { public void Create(Expert item) {
I want to clarify that my repositories cannot add, update or delete an entity from my damage, rather, I will have a consumption code (possibly at the service level), a new one, and then add directly to it ... when my application is ready , it will call Commit ().
It does two things. This allows my consumer code to determine how it wants the object to be stored. Either the consumption code can call .Create () directly in the repository to save the object without uow, or the consumption code can start with uow, call .Add () in uow, and then, when .Commit () is called, uow will go through all entities and by type of action (add, update deletion), update the corresponding repository and execute the TSQL code.
Now the problem I am facing is when I look at the Add, Update and Delete collections in my damage. Here is the code snippet:
public void Commit() { using (TransactionScope tx = new TransactionScope()) { try { foreach (object item in addedItems) { if (item.GetType() == typeof(Expert)) { IRepository<Expert> repository = new ExpertRepository(); repository.Create((Expert)item); } } } } }
I need to determine the type of entity that is in the collection of objects through the variable item. Then I need to update this repository (also providing the correct type to the IRepository interface) and then call .Create ().
This is all good and good, but I do not want to have these conditional checks for all possible entities, for the entity interface and the entity repository sitting in my loss. This is very bad.
I know that an IoC container (e.g. Unity) can help here, but is there an IoC container that can resolve common types at runtime? I ask: b / c IRepository needs to be entered correctly to be var, which contains an instance of this entity repository.
I made some design decisions here, for example, set strong typing using repositories, not UOW. For example, I do not want the .Create () method to be in the repository that accepts an object of type, especially. since my repositories have a one-to-one relationship with my entities (Expert, ExpertRepository).
I also decided that since most of the calls to the repository are the same, I do not want to have an interface for each repository (it also ExpertRepository implements IExpertRepository). It doesn't make sense, I think using generics here is the answer.
But it all comes down to the problem in my damage. How do I get what I need to implement it correctly.
Any suggestions or pointers in the right direction will be appreciated.
Thanks!