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.
Related
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.
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'm new to NHibernate and not very good at C#, but I'm learning. I have a DataProvider class which provides data for my application using NHibernate 3. It's structured pretty much identical to Steve Bohlen's Summer of NHibernate videos.
I've noticed that I'm about to repeat my code a lot and I want to simplify my DataProvider. For example I have two business classes called Instrument and Broker. The method to add an Instrument in my DataProvider is:
public int AddInstrument(Instrument instrument)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(instrument);
_session.Flush();
tx.Commit();
return newId;
}
catch (NHibernate.HibernateException)
{
tx.Rollback();
throw;
}
}
}
and the AddBroker class looks remarkably similar (just find and replace). So I thought maybe I could use Generics to solve the problem. Something like:
public class DataProvider <TEntity>
{
public int AddEntity(TEntity entity)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(entity);
_session.Flush();
tx.Commit();
return newId;
}
catch (NHibernate.HibernateException)
{
tx.Rollback();
throw;
}
}
}
}
With this I can pass in a Broker, an Instrument or anything and I save myself a lot of repetitive code. The problem I'm having is that in my Test class I create a new DataProvider each time a test is run like this:
#region Fields
private DataProvider _provider;
private SessionManager _sessionManager;
private NHibernate.ISession _session;
#endregion
[SetUp]
public void Setup()
{
DatabaseSetUp();
_session = _sessionManager.GetSession();
_provider = new DataProvider(_session); // problem here
}
Using generics I have to pass in the object type to my DataProvider. Can you think of a way to solve this? I am a novice programmer and I am wondering if I am going down the right path. Should I be doing something totally different?
UPDATE
I have tried to implement Groo's answer but am having some issues. Here's what I've done.
IRepo.cs
interface IRepo<T>
{
int Add<Entity>(Entity entity);
void Delete<Entity>(Entity entity);
void GetById<Entity>(int Id);
}
BaseRepo.cs
public abstract class BaseRepo <T> : IRepo <T>
{
private ISession _session;
#region SessionManagement
public BaseRepo(ISession session)
{
_session = session;
}
public ISession Session
{
set { _session = value; }
}
#endregion
public int Add<Entity>(Entity entity)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(entity);
_session.Flush();
tx.Commit();
return newId;
}
catch (NHibernate.HibernateException)
{
tx.Rollback();
throw;
}
}
}
// other methods omitted for brevity
}
IRepoFactory.cs
interface IRepoFactory
{
IInstrumentRepo CreateInstrumentRepo(ISession s);
}
RepoFactory.cs
public class RepoFactory : IRepoFactory
{
public IInstrumentRepo CreateInstrumentRepo(ISession s) // problem here
{
return new InstrumentRepo(s);
}
}
IInstrumentRepo.cs
interface IInstrumentRepo : IRepo<Instrument>
{
}
InstrumentRepo.cs
public class InstrumentRepo : BaseRepo<Instrument>, IInstrumentRepo
{
public InstrumentRepo(ISession s) : base(s) { }
}
In RepoFactory.cs I get this error:
Inconsistent accessibility: return type 'MooDB.Data.IInstrumentRepo' is less accessible than method 'MooDB.Data.RepoFactory.CreateInstrumentRepo(NHibernate.ISession)'
Any ideas what I'm missing?
First of all, to address your Test Setup question: the term Repository might suggest that it should be a long lived, persistent object, but Repositories used in DAL operations should actually be lightweight stateless objects with short lifetimes: you instantiate one when you need it, and throw it away as soon as you're done. When you think about this is terms of performance, you can easily instantiate millions of them per second.
Combined with NHibernate's short lived Session instances, this is how your code is meant to look like when everything is in place:
using (var session = SessionManager.OpenSession())
{
// create an instrument repo
IInstrumentRepo instruments = DAL.RepoFactory.CreateInstrumentRepo(session);
var guitar = instruments.Find(i => i.Type == "Guitar");
// create a customer repo
ICustomerRepo customers = DAL.RepoFactory.CreateCustomerRepo(session);
var cust = customers.Find(c => c.Name == "Mark")
// do something -> changes will be persisted by NH when session is disposed
cust.Instruments.Add(guitar);
}
That's the general idea. Now, let me explain it in more detail:
You may have noticed that each repo has its own interface, and is created through a repo factory. Using a factory to create repositories means you can easily create mock repo factories, which will create any custom implementation of a repository for testing.
Each repo interface inherits from the base interface generic interface, IRepo<T>. This allows you to use a generic repository in 99% of cases, but still leave room to implement a custom query method specific to, say, Customer entities only:
public interface IInstrumentRepo : IRepo<Instrument>
{
// nothing to do here
}
public interface ICustomerRepo : IRepo<Customer>
{
// but we'll need a custom method here
void FindByAddress(string address);
}
public interface IRepo<T>
{
T GetById(object id);
T Save(T item);
}
This means that your repo implementations will, in most cases, simply inherit from the base abstract class (I named it BaseRepo, but it's essentially what your DataProvider class does right now):
class InstrumentRepo : BaseRepo<Instrument>, IInstrumentRepo
{
// no need to implement anything here except pass the session downwards
public InstrumentRepo(ISession s) : base(s) { }
}
Your factory will simply need to instantiate the proper repository when asked:
public class RepoFactory : IRepoFactory
{
public IInstrumentRepo CreateInstrumentRepo(ISession s)
{
return new InstumentRepo(s);
}
}
And you will need to use the Singleton pattern in a, say, DAL class to hold the factory (there are slightly better ways to do this, using DI, but for now this will do just fine):
public static class DAL
{
// repo factory is pretty lightweight, so no need for fancy
// singleton patterns
private static readonly IRepoFactory _repoFactory = new RepoFactory();
public static IRepoFactory RepoFactory
{
get { return _repoFactory; }
}
}
The answer to your question is Absolutely Yes!
This is what generics are meant for.
You are in the right way.
This argument is really too long to discuss here but you can find a lot of usefull info in this article:
http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
It helps me a lot to create my generic nhibernate Dao
Your data provider class doesn't necessarily need to be generic - you can just make the AddEntity method itself generic. Then you instantiate a DataProvider instance, and call (for example) its AddEntity<Instrument> method. Your class would look like this:
public class DataProvider
{
public int AddEntity<TEntity>(TEntity entity)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(entity);
_session.Flush();
tx.Commit();
return newId;
}
catch (NHibernate.HibernateException)
{
tx.Rollback();
throw;
}
}
}
}
I am in a situation where we need to modify what is being returned from the static repository in a 3rd party open-source application (NopCommerce). The problem is that they use static repositories, so I can't merely inherit an interface and DI my own repository. I'm trying to do this without modifying the NopCommerce code-base... any fresh ideas?
Edit: I want NopCommerce to use my repos, rather than have my code use theirs.
You could abstract away their stuff by creating an interface of your own and a class implementation that delegates to NopCommerce. Then have your code use the interface instead of directly accessing NopCommerce's classes. You can modify the output of NopCommerce inside your class before the result is returned to your application.
And as an added bonus you could also mock the interface to do some tests that didn't require the full-blown repository implementations.
Something like this, in code:
public interface IRepository
{
MyItem GetItem(int id);
}
public class MyNopCommerceWrapper : IRepository
{
public MyItem GetItem(int id)
{
// I have no idea what NopCommerce API looks like, so I made this up.
var myItem = NopCommerce.GetItem(id);
ModifyMyItem(myItem);
return myItem;
}
}
We are currently on a really, really tight deadline, and this problem was not forseen. So I am thinking of first starting with a poor man's static interface/poor man's DI like the following (so I don't have to modify the entire solution). Then at a later time, when we are not-so-pressed for time, change over to use an interface and dependency injection and submit a patch to NopCommerce:
// Poor-man's static interface (DI).
public static class OriginalBuiltInStaticClass {
private static IMyNewClass _myNewClass;
public static void Inject(IMyNewClass myNewClass) {
_myNewClass = myNewClass;
A = _myNewClass.A;
B = _myNewClass.B;
C = _myNewClass.C;
}
public static Action A = CopySimpleRenameBuiltInStaticClass.A;
public static Func<int, string> B = CopySimpleRenameBuiltInStaticClass.B;
public static Action C = CopySimpleRenameBuiltInStaticClass.C;
}
// Original vendor class which was copied and renamed.
public static class CopySimpleRenameBuiltInStaticClass {
public static void A() {
Console.WriteLine("OriginalBuiltInStaticClass.A()");
}
public static string B(int id) {
Console.WriteLine("OriginalBuiltInStaticClass.B()");
return id.ToString();
}
public static void C() {
Console.WriteLine("OriginalBuiltInStaticClass.C()");
}
}
// Creating an interface to merge into trunk of NopCommerce (convert static repositories)
public interface IMyNewClass {
void A();
string B(int id);
void C();
}
// Implementation of interface.
public class MyNewClass : IMyNewClass {
public void A() {
Console.WriteLine("MyNewClass.A()");
}
public string B(int id) {
Console.WriteLine("MyNewClass.B()");
return id.ToString();
}
public void C() {
CopySimpleRenameBuiltInStaticClass.C();
}
}
Any thoughts?
Sounds like a job for Facade.
Im faced with an impending upgrade to an ASP.NET site and I am thinking of introducing DI using Unity. I have researched the ASP.NET DI side of things and have 2 options (Global.asax or IHttpModule). Im happy to use either.
As always, there is a legacy object model in place that I would like to upgrade/change. I would like to go down the route of Constructor injection (passing in the DAO) however, each object has a mix of static and instance methods that both currently call into the DB using SqlCommand objects themselves. I want this removed to provide DB independence, therefore can anyone suggest the best way to do the DI in this case? Im open to drastic changes if they are needed.
public class ExampleClass
{
public ExampleClass(int test)
{
TestProperty = test;
}
public int TestProperty {get; set;}
public int Save()
{
// Call DB and Save
return 1;
}
public static ExampleClass Load(int id)
{
// Call DB and Get object from DB
return new ExampleClass(1);
}
}
Thanks for any suggestions
Matt
If you remove all static methods and introduce some abstractions you should be good to go:
public class ExampleClass
{
public int TestProperty { get; set; }
}
public interface IRepository
{
ExampleClass Load(int id);
int Save();
}
public class RepositorySql: IRepository
{
// implement the two methods using sql
}
and in your ASP page:
private IRepository _repo = FetchRepoFromContainer();
public void Page_Load()
{
var someObj = _repo.Load(1);
// ... etc
}