How do I go about creating a class which wraps all EF repository calls in a Using statement whilst also supporting an injectable interface of the repository?
I can't seem to wrap my head around having this class support 2 different types of instantiation.
public class MyClass(IRepo repo)
{
_repo = repo;
}
public void MyMethod()
{
using ( var db = new DbContxt() )
{
var repo = new Repo(db);
repo.GetById(1);
}
}
In essence, the life-time of the 'db' object is the lifetime of the method call. Whereas the lifetime of 'db' would be managed outside of the class if injected.
You could structure it this way:
public class MyClass
{
private readonly IRepo _repo;
//or if you want a parameterless constructor...
public MyClass() : this(new Repo()) { }
public MyClass(IRepo repo)
{
_repo = repo;
}
public MyObject MyMethod(int id)
{
_repo.GetById(id);
}
}
public interface IRepo
{
MyObject GetById(int id);
}
public class Repo : IRepo
{
public MyObject GetById(int id)
{
using ( var db = new DbContext())
{
//do your db related stuff here
}
}
}
You would need a way of injecting an instance of Repo into MyClass so maybe take a look at IoC.
This way, you can easily mock IRepo for testing purposes.
You shouldn't do it that way. Have a parameterless constructor for your Repo, and instantiate the DbContext there. You can also have an overload for it that takes a DbContext, but you don't have to go about it that way. The point is to let each layer only worry about what it needs on its own. Let the IOC container inject everything as it is created, don't make objects for a different layer inside your methods.
Related
What is the recommended way to instantiate another class inside a sealed class:
public sealed class AvayaService
{
private static Lazy<AvayaService> lazy =
new Lazy<AvayaService>(() => new AvayaService());
public static AvayaService AvayaServiceInstance
{
get
{
if (!lazy.IsValueCreated)
lazy = new Lazy<AvayaService>(() => new AvayaService());
return lazy.Value;
}
}
private AvayaService()
{
}
public static Response GetResponse(Request request)
{
var _repository = new Repository(); // what is the best way to get the instance here
}
}
public class Repository : IRepository
{
...
}
I am trying to learn sealed class and lazy instantiation however I am pondering over what should be the recommended way to instantiate another class in a sealed class?
There's no "recommendations" in this area. If you've read recommendations, read again, most probably it was just an exercise. It gives you an idea, but using this idea in a real project is up to you. Sometimes those exercises demonstrate an opposite approaches. Sometimes the repository owner will dictate the style which is against of any rules you've read before, and it's totally fine.
Here's another instantiation exercise which I think is helpful to try: to never instantiate anything except value objects. Delegate instantiation to a container. Avoid singleton pattern, but register your service as a singleton in your container. In this way your code will look like:
public sealed class AvayaService
{
private readonly IRepository _repository;
public AvayaService(IRepository repository)
{
if(repository == null)
throw new ArgumentNullException();
_repository = repository;
}
public static Response GetResponse(Request request)
{
// use _repository
}
}
I have a problem with unit testing.
I have a standart Reprository and UnitOfWork pattern.
For example, I have a UnitOfWork class:
public class UnitOfWork : IDisposable
{
private readonly MyDbContext _context;
... repositories
private IMyEntityRepository _myEntityRepository;
...
}
UnitOfWok used in another part of program witch make some special operations with entities. For example, there is a method, whitch use UnitOfWork:
public IEnumerable<MyClass> MyMethod()
{
using (_unitOfWork = new UnitOfWork())
{
var myEntities= _unitOfWork.MyEntityRepository.Get();
var result = ... some logic to convert myEntities collection to IEnumerable<MyClass>
return result;
}
}
My question is how to write unit tests for MyMethod if there is consruction using(_unitOfWork = new UnitOfWork)? How could I use fake UnitOfWork with Fake context in that case? Thanks for any advice.
To make your classes more fake-able and testable I would suggest abstracting your UnitOfWork and Repositories if possible and then use a factory to inject them into the classes that depend on them.
public interface IUnitOfWork : IDisposable {
... repositories
IMyEntityRepository MyEntityRepository;
...
}
And your UnitOfWork will derive from that interface
public class UnitOfWork : IUnitOfWork {...}
IUnitOfWorkFactory
public interface IUnitOfWorkFactory {
IUnitOfWork Create();
}
With that, a dependent class can then look like this
public class MyDependentClass {
private readonly IUnitOfWorkFactory unitOfWorkFactory;
public MyDependentClass (IUnitOfWorkFactory unitOfWorkFactory) {
this.unitOfWorkFactory = unitOfWorkFactory;
}
public IEnumerable<MyClass> MyMethod() {
using (var _unitOfWork = unitOfWorkFactory.Create()) {
var myEntities= _unitOfWork.MyEntityRepository.Get();
var result = ... some logic to convert myEntities collection to IEnumerable<MyClass>
return result;
}
}
}
Now you can mock/fake your UnitOfWork and Repositories with no need to fake the Context.
Lets say you want to test/verify that the UOW is actually disposed of after calling MyMethod
(I'm using Moq and FluentAssert for demonstrative purposes)
You can construct a test as follows:
[TestMethod]
public void UOW_Should_Be_Disposed() {
//Assert
var fake_entities = Enumerable.Range(1, 10).Select(i => new MyEntity());
var mockRepository = new Mock<IMyEntityRepository>();
mockRepository.Setup(m => m.Get()).Returns(fake_entities);
var mockUOW = new Mock<IUnitOfWork>();
mockUOW.Setup(m => m.MyEntityRepository).Returns(mockRepository.Object);
var mockFactory = new Mock<IUnitOfWorkFactory>();
mockFactory.Setup(m => m.Create()).Returns(mockUOW.Object);
//Act
var sut = new MyDependentClass(mockFactory.Object);
var output = sut.MyMethod().ToList();
//Assert
output.Should().NotBeNull();
output.Should().HaveCount(10);
output.Should().ContainItemsAssignableTo<MyClass>();
mockUOW.Verify(m => m.Dispose());
}
The above shows how you can test everything easily using the frameworks mentioned.
Hope this helps
You have to inject a factory of UnitOfWork into the class that contains the MyMethod method via constructor injection like this:
public class MyClass
{
private readonly Func<UnitOfWork> unitOfWorkFactory;
public MyClass(Func<UnitOfWork> unitOfWorkFactory)
{
this.unitOfWorkFactory = unitOfWorkFactory;
}
public IEnumerable<MyClass> MyMethod()
{
using (unitOfWork = unitOfWorkFactory())
{
//..
}
}
}
Please note that the class takes a Func<UnitOfWork> instead of a UnitOfWork because I am assuming that you want each call to MyMethod to have a new instance of UnitOfWork.
In your tests, you create a fake UnitOfWork and then you can pass it to the MyClass instance like this:
var sut = new MyClass(() => fakeInstance);
You also need to make sure that UnitOfWork is fakeable. For example, since it is a concrete class, you need to make sure that the relevant methods are virtual. Another approach is to have an interface IUnitOfWork that UnitOfWork implements and that MyClass uses.
what is the 'best' way to manage the lifecycle of a disposable object when it is injected into another class. The example I keep running into is when running database queries using entity framework in a class that has a long lifetime.
Here is an example
public class CustomerViewModel
{
private ICustomerRepository _customerRepository;
public CustomerViewModel(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public void AddCustomer(Customer customer)
{
_customerRepository.Customers.Add(customer);
_customerRepository.SaveChanges();
}
}
The code above looks perfectly innocent to me, however the _customerRepository object exists for as long as the CutomerViewModel exists for, which is much longer than it should.
If I were writting this code without DI i would do this:
public class CustomerViewModel
{
public void AddCustomer(Customer customer)
{
using (var customerRepository = new CustomerRepository())
{
customerRepository.Customers.Add(customer);
customerRepository.SaveChanges();
}
}
}
Which handles the lifecycle of CustomerRepository correctly.
How is this supposed to be managed when a class requires a Disposable object to have a shorter lifetime than itself?
The method I am using now is to create a RepositoryCreator object, which knows how to initialize a repository, but this feels wrong:
public class CustomerViewModel
{
private ICustomerRepositoryCreator _customerRepositoryCreator;
public CustomerViewModel(ICustomerRepositoryCreator customerRepositoryCreator)
{
_customerRepositoryCreator= customerRepositoryCreator;
}
public void AddCustomer(Customer customer)
{
using (var customerRepository = _customerRepositoryCreator.Create())
{
customerRepository.Customers.Add(customer);
customerRepository.SaveChanges();
}
}
}
UPDATE
So would doing something like this be preferable, it could be made generic but for the sake of this example I will not do this.
public class CustomerViewModel
{
private ICustomerRepository _customerRepository;
public CustomerViewModel(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public void AddCustomer(Customer customer)
{
_customerRepository.Add(customer);
}
}
public class CustomerRepository : ICustomerRepository
{
private readonly DbContext _dbContext;
public CustomerRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Add(Customer customer)
{
_dbContext.Customers.Add(customer);
_dbContext.Customers.SaveChanges();
}
}
And have a proxy which manages lifetime
public class CustomerRepositoryLifetimeProxy : ICustomerRepository
{
private readonly _container;
public CustomerRepositoryLifetimeProxy(Container container)
{
_container = container;
}
public void Add(Customer customer)
{
using (Container.BeginScope()) //extension method
{
ICustomerRepository cRepo = Container.Resolve<ICustomerRepository>();
cRepo.Add(customer);
} // releases the instance
}
}
If this is better, should the Proxy know about the DI container, or should it rely on a factory?
The problem here is that your AddCustomer method in your ViewModel does to much. The viewmodel should not be responsible of handling business logic, and the repositories consumer shouldn't know nothing about committing a unit of work and should not be able to add a customer to the list of customers.
So instead, refactor your ICustomerResository to the following:
public interface ICustomerRepository
{
void Add(Customer customer);
}
In this case, the Add method should be atomic and do the commit itself. This way the viewmodel can depend on that interface and in case the viewmodel outlives the customer repository, you can wrap the real repository with a proxy:
public class CustomerRepositoryProxy : ICustomerRepository
{
private readonly Func<ICustomerRepository> repositoryFactory;
public CustomerRepositoryProxy(Func<ICustomerRepository> repositoryFactory) {
this.repositoryFactory = repositoryFactory;
}
public void Add(Customer customer) {
var repository = this.repositoryFactory.Invoke();
repository.Add(customer);
}
}
Of course this will start to become quite cumbersome if you have dozens of those IXXXRepository interfaces. In that case, you might want to migrate to one generic interface instead:
public interface IRepository<TEntity>
{
void Add(TEntity entity);
}
This way you can have one single proxy for all repositories:
public class RepositoryProxy<TEntity> : IRepository<TEntity>
{
private readonly Func<IRepository<TEntity>> repositoryFactory;
public CustomerRepositoryProxy(Func<IRepository<TEntity>> repositoryFactory) {
this.repositoryFactory = repositoryFactory;
}
public void Add(TEntity entity) {
var repository = this.repositoryFactory.Invoke();
repository.Add(entity);
}
}
In that case (assuming you wire your object graphs by hand) you can build up the viewmodel as follows:
new CustomerViewModel(
new RepositoryProxy<Customer>(
() => new CustomerRepository(unitOfWork)));
You can even take it one step further and implement the command/handler pattern and query/handler pattern. In that case you don't inject a IRepository<Customer> into your view model, but you inject an ICommandHandler<AddCustomer> into the view model and instead of injecting the AddCustomerCommandHandler implementation into the view model, you inject a proxy that creates the real handler when needed:
public class LifetimeScopedCommandHandlerProxy<TCommand> : ICommandHandler<TCommand>
{
private readonly Func<ICommandHandler<TCommand>> decorateeFactory;
public LifetimeScopedCommandHandlerProxy(
Func<ICommandHandler<TCommand>> decorateeFactory) {
this.decorateeFactory = decorateeFactory;
}
public void Handle(TCommand command) {
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(command);
}
}
The view model will look as follows:
public class CustomerViewModel
{
private ICommandHandler<AddCustomer> addCustomerCommandHandler;
public CustomerViewModel(ICommandHandler<AddCustomer> addCustomerCommandHandler) {
this.addCustomerCommandHandler = addCustomerCommandHandler;
}
public void AddCustomer(Customer customer)
{
this.addCustomerCommandHandler.Handle(new AddCustomer(customer));
}
}
And the object graph will look similar as before:
new CustomerViewModel(
new LifetimeScopedCommandHandlerProxy<AddCustomer>(
() => new AddCustomerCommandHandler(unitOfWork)));
Of course, it will be much easier building these object graphs when using a container.
UPDATE
If you use a DI container, and you're not running in something like a web request, you will have to start a new 'scope' or 'request' explictly to inform the container what to do. With Simple Injector your proxy will looks like this:
public class LifetimeScopedCommandHandlerProxy<TCommand> : ICommandHandler<TCommand>
{
private readonly Container container;
private readonly Func<ICommandHandler<TCommand>> decorateeFactory;
// Here we inject the container as well.
public LifetimeScopedCommandHandlerProxy(Container container,
Func<ICommandHandler<TCommand>> decorateeFactory)
{
this.container = container;
this.decorateeFactory = decorateeFactory;
}
public void Handle(TCommand command) {
// Here we begin a new 'lifetime scope' before calling invoke.
using (container.BeginLifetimeScope())
{
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(command);
}
// When the lifetime scope is disposed (which is what the using
// statement does) the container will make sure that any scope
// instances are disposed.
}
}
In that case your configuration might look like this:
// This instance lives as long as its scope and will be disposed by the container.
container.RegisterLifetimeScope<IUnitOfWork, DisposableUnitOfWork>();
// Register the command handler
container.Register<ICommandHandler<AddCustomer>, AddCustomerCommandHandler>();
// register the proxy that adds the scoping behavior
container.RegisterSingleDecorator(
typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerProxy<>));
container.Register<CustomerViewModel>();
In general it is up to the creator to dispose a disposable object as soon es it is done with its usage. If your injected object can live through entire application lifecycle, i.e. without needing to dispose it in the meantime, than the normal DI approach (your first code block) is a good way to go. However, if you need to dispose the object as soon as possible, than a factory approach makes much more sense (last code block).
I don't know how manage properly the interfaces in C#. My goal is to have an abstract class for my Business Layer Services that have some common methods (like Save(), Dispose()), that call different DAL repository methods. I wish to avoid to repeat in all my services something like:
public Save()
{
repository.Save();
}
I have a scenario similar to that:
Interface
namespace Common
{
public interface IRepository
{
void Save;
void Dispose;
}
}
DAL
namespace DAL
{
public Repository : IRepository
{
public void Save() {};
public void Dispose() {};
public void Add() {}
}
}
BL
namespace BL
{
public abstrac BaseService
{
protected IRepository repository;
protected BaseService(IRepository repo)
{
repository = repo;
}
public Save()
{
repository.Save();
}
}
//...
//Tentative 1
public Service : BaseService
{
private Repository rep;
public Service()
: base(new DAL.Repository())
{
rep = base.repository; // ERROR: cannot convert IRepository to Repository
}
}
}
I tried also this:
//Tentative 2
public Service : BaseService
{
private IRepository rep;
public Service()
: base(new DAL.Repository())
{
rep = base.repository; // OK
}
public void Add()
{
rep.Add() // ERROR: IRepository doesn't contain a definition for 'Add'
}
}
I know I could define in the interface all the methods I want to use, but I'll will have to manage a lot of problems with generic types and, as you should have understand from my question, I'm quite new in C# and I wish to avoid complexity is is possible, utill I'll be more expert at least :)
Firstly I think you're having a name clash with you member
IRepository rep.
Try using
DAL.IRepository rep
The reason that you're getting an error is that you've defined "Add" as something unique to "Repository". Your member variable is an "IRepository" allowing you to put anything that implements "IRepository" onto it.
Just because you CAN put a Repository into it, doesn't mean that everything on it is going to be a repository. (Think of it look good 'ol fingers and thumbs, all thumbs are fingers, but not all fingers are thumbs)
If you NEED to call add on any repository, then add it to the interface. Else, you need to decide whether or not that member should be IRepository or Repository.
Alternatively, you COULD use
Repository myRep = rep as Repository;
if(rep!=null)
{
myRep.Add();
...
profit();
}
public Service()
: base(new DAL.Repository())
{
rep = (Repository)base.repository;
}
This way u will get the Add() service which is not a part of IRepository but a newer implementation in the extended class.
Seeing as your main problem is the lack of accessibility to the Add method, and seeing as this is a relative common method anyway, I would firstly recommend adding it to your IRepository, so it looks like this:
public interface IRepository
{
void Add();
void Save();
void Dispose();
}
You would then implement your appropriate repositories whilst inheriting from IRepository. Now, understandably you may want to be able to access custom methods on a Repository. In order to resolve this what you could do is have your BaseService accept a generic repository:
public BaseService<T> where T : IRepository
{
protected T repository { get; set; }
protected BaseService(T repo)
{
repository = repo;
}
}
Then a service would look like this
public UserService : BaseService<UserRepository>
{
public UserService() : base(new DAL.UserRepository())
{
// base.Repository is now a UserRepository.
}
}
With this implementation your UserService will be able to access all of the methods that UserRepository exposes, as it's strongly typed with the generic. Hope this helps.
I am using simple repository pattern of Subsonic 3 to store and get values from database. I want to know if I should use Singleton patten to create SimpleRepository or should create one whenever is needed. Like if I have Person class like this:
public class Person
{
public void Save()
{
var repo=new SimpleRepository("constr"); //CREATE REPO HERE
repo.Add<Person>(this);
}
public void Load(int id)
{
var repo=new SimpleRepository("constr");//CREATE REPO HER
.....
}
}
Or access repo like this
public class Person
{
public void Save()
{
var repo=RepoHelper.GetRepository();//GET FROM SINGLETON OBJECT
repo.Add<Person>(this);
}
public void Load(int id)
{
var repo=RepoHelper.GetRepository();
.....
}
}
I use a singleton class for it. It seems to be the right thing when you have a centralized data store. I allows you to manage the type of repository in one place. Is also has the advantage that it makes it easier to switch from reposition type.
public static class Repository
{
static SimpleRepository repo;
public static IRepository GetRepository()
{
if (repo == null)
{
lock (repo)
{
repo = new SimpleRepository("NamedConnectionString",
SimpleRepositoryOptions.RunMigrations);
}
}
return repo;
}
}
Ps. I also build a base record class to do a Save() and to manage foreign relations.