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;
}
}
}
}
Related
I'am developing a small system and i developed the classic generic repository. For now, i have the following architecture for my DAL.
public interface IRepositorio<T> where T : class
{
T Get(long id);
long Insert(T obj);
bool Update(T obj);
bool Delete(T obj);
}
public abstract class Repositorio<T> : IRepositorio<T> where T : class
{
public IDbConnection Connection
{
get
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["DBFila"].ConnectionString);
}
}
public T Get(long id)
{
//...
}
public long Insert(T obj)
{
//...
}
public bool Update(T obj)
{
//...
}
public bool Delete(T obj)
{
//...
}
}
My concrete repository looks like this:
public class FilaRepositorio : Repositorio<FilaRepositorio>
{
public FilaRepositorio()
{
}
public void SomeCustomMethod()
{
// Some custom method
}
}
I am also using Simple Injector to follow the IoC and DI patterns, for this reason, when i try to call "SomeCustomMethod()" i dont have access to it (obviously). Look:
public class Processador
{
private IRepositorio<FilaModel> _repoFila;
public Processador(IRepositorio<FilaModel> repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod(); // <-- wrong
((FilaRepositorio)_repoFila).SomeCustomMethod();// <-- works
}
}
Given this i have some questions:
Is a good or acceptable practice to make that cast (FilaRepositorio)?
If its not a good practice, how to write good code for this case?
There are a few options available. The main problem with making the cast is that it is an implementation concern.
What would happen if the injected object was not a FilaRepositorio?
By making the cast you are tightly coupling the class to an implementation concern that is not guaranteed to be the inject dependency. Thus the constructor is not being entirely truthful about what it needs to perform its function.
This demonstrates the need to practice Explicit Dependencies Principle
The Explicit Dependencies Principle states:
Methods and classes should explicitly require (typically through
method parameters or constructor parameters) any collaborating objects
they need in order to function correctly.
One way to avoid it would be to make a derived interface that explicitly exposes the desired functionality of its dependents.
public interface IFilaRepositorio : IRepositorio<FilaModel> {
void SomeCustomMethod();
}
public class FilaRepositorio : Repositorio<FilaModel>, IFilaRepositorio {
public void SomeCustomMethod() {
//...other code removed for brevity.
}
}
and have the Processador depend on that more targeted abstraction.
Now there is no need for the cast at all and the class explicitly expresses what it needs.
public class Processador {
private readonly IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila) {
_repoFila = repoFila;
}
public void Processar() {
_repoFila.SomeCustomMethod(); // <-- works
}
}
If you need to access a specific method from any part of your application, then that specific method must be part of your abstraction, or else there is no guarantee that you may use it when changing the concrete class.
I do not believe that your use of casting is a good idea at all, what is usually done in this case is to create a specific interface which defines any other method you could need to use:
public interface IFilaRepositorio : IRepositorio<Fila>
{
void SomeCustomMethod();
}
And than use and declare that specific interface in any part of your code where you believe you need to use it:
public class Processador
{
private IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod();
}
}
I just started to learn Decorator Design Pattern, unfortunately i had to go through various refrences to understand the Decorator pattern in a better manner which led me in great confusion. so, as far as my understanding is concern, i believe this is a decorator pattern
interface IComponent
{
void Operation();
}
class Component : IComponent
{
public void Operation()
{
Console.WriteLine("I am walking ");
}
}
class DecoratorA : IComponent
{
IComponent component;
public DecoratorA(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("in the rain");
}
}
class DecoratorB : IComponent
{
IComponent component;
public DecoratorB(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("with an umbrella");
}
}
class Client
{
static void Main()
{
IComponent component = new Component();
component.Operation();
DecoratorA decoratorA = new DecoratorA(new Component());
component.Operation();
DecoratorB decoratorB = new DecoratorB(new Component());
component.Operation();
Console.Read();
}
}
But can the below code also be Decorator Pattern?
class Photo
{
public void Draw()
{
Console.WriteLine("draw a photo");
}
}
class BorderedPhoto : Photo
{
public void drawBorder()
{
Console.WriteLine("draw a border photo");
}
}
class FramePhoto : BorderedPhoto
{
public void frame()
{
Console.WriteLine("frame the photo");
}
}
class Client
{
static void Main()
{
Photo p = new Photo();
p.Draw();
BorderedPhoto b = new BorderedPhoto();
b.Draw();
b.drawBorder();
FramePhoto f = new FramePhoto();
f.Draw();
f.drawBorder();
f.frame();
}
}
My Understanding
From the second example given by me, we can call all the three methods, but from the first example i wont be able to get access to all the three methods by creating a single object.
It should be a comment, but I have too many words.
For example, you have an object and interface, like Repository : IRepository.
public interface IRepository
{
void SaveStuff();
}
public class Repository : IRepository
{
public void SaveStuff()
{
// save stuff
}
}
and client, which probably was written by someone else
class RepoClient
{
public void DoSomething(IRepository repo)
{
//...
repo.SaveStuff();
}
}
And once you decided, that ALL calls to repository should be logged. But you have a problem: the Repository class is from an external library and you don't want to change that code. So you need to extend the Repository's behavior that you use. You write RepositoryLogDecorator : IRepository, and inside on each method do the logging, like
public class RepositoryLogDecorator : IRepository
{
public IRepository _inner;
public RepositoryLogDecorator(IRepository inner)
{
_inner = inner;
}
public void SaveStuff()
{
// log enter to method
try
{
_inner.SaveStuff();
}
catch(Exception ex)
{
// log exception
}
// log exit to method
}
}
So, before you could use client as
var client = new RepoClient();
client.DoSomething(new Repository());
but now you can use
var client = new RepoClient();
client.DoSomething(new RepositoryLogDecorator(new Repository()));
Note, that this is a very simple example. In real projects, where object created primary with DI container, you will be able to use decorator by changing some config.
So, decorator is used to extend functionality of object without changing object or client.
Another benefit of decorator: your decorator does not depend on Repository implementation. Only depends from an interface IRepository. Why this is an advantage? If somehow you decide to write you own implementation of IRepository
public class MyAwesomeRepository : IRepository
{
public void SaveStuff()
{
// save stuff, but AWESOME!
}
}
you will be able to automatically decorate this with decorator, which already exist
var client = new RepoClient();
client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));
Want to see example from real software? (just as sample, code is ugly, I know) => go here
There is this PatternCraft series on Youtube that explains Design Patterns with Starcraft, you should check the video about Decorators here.
In the video above the author gives an example with a Marine and WeaponUpgrade.
In the game you will have a Marine and then you can upgrade its weapon:
marine = new WeaponUpgrade(marine);
Note that you still have a marine there, it is not a new unit, it is the same unit with things that modifies its attributes.
public class MarineWeaponUpgrade : IMarine
{
private IMarine marine;
public MarineWeaponUpgrade(IMarine marine)
{
this.marine = marine;
}
public int Damage
{
get { return this.marine.Damage + 1; } // here
set { this.marine.Damage = value; }
}
}
You do that by creating a class that implements the same interface as your unit and access your unit properties to modify values.
There is a Kata on CodeWars challenging you to complete the Weapon and Armor decorators for a marine.
Per GOF page Decorator desing pattern:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
In your second example you are using inheritance to extend behaviour of a class, I believe this is technically not a Decorator design pattern.
The decorator pattern allows you to add a specific behavior to an individual object of a given type without affecting other instances of that same type.
In your second example, which is normal inheritance, all instances of the class inherit the modified behavior.
The second example is not a decorate pattern, since an essential ingredient to decorator pattern is that the object accepts one of its kind and possibly enhance it.
An instances of this in the first example is
public DecoratorA(IComponent c)
{
component = c;
}
Also, the goal of the decorator pattern is to create "one" object, then decorate it by passing it through different filters or decorators.
Hence the line
DecoratorA decoratorA = new DecoratorA(new Component());
Should be
DecoratorA decoratorA = new DecoratorA(component );
I am trying to implement the strategy pattern in my repository layer using SM and generics. For that I have an interface, IPocoRepository, which has a concrete implementation using Entity Framework. This I have managed to wire up in my Bootstrapper-file:
For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>));
The problem appears when I try to implement caching for this interface. In my cached class I want an instance of the base repository class, so that I can keep my design DRY. Let me outline how these three files look:
public interface IPocoRepository<T>
{
IQueryable<T> GetAll();
...
public class EntityFrameworkRepository<T> : IPocoRepository<T> where T : class
{
public IQueryable<T> GetAll()
{
...
public class CachedRepository<T> : IPocoRepository<T> where T : class
{
private IPocoRepository<T> _pocoRepository;
public CachedRepository(IPocoRepository<T> pr)
{
_pocoRepository = pr;
}
public IQueryable<T> GetAll()
{
var all = (IQueryable<T>)CacheProvider.Get(_cacheKey);
if (!CacheProvider.IsSet(_cacheKey))
{
all = _pocoRepository.GetAll();
...
Edit: I want StructureMap to return CachedRepository when IPocoRepository is requested, except when requested for in CachedRepository - then I want it to return EntityFrameworkRepository.
I know this is simple when dealing with non-generic classes:
For<ICountyRepository>().Use<CachedCountyRepository>()
.Ctor<ICountyRepository>().Is<CountyRepository>();
I tried searching the documentation for how to do this, but couldn't find anything. Any help would be appreciated!
Ok, this isn't too hard. You can use a type interceptor. Given you have the following classes:
public interface IRepository<T>{}
public class Repository<T>:IRepository<T>{}
public class RepositoryCache<T> : IRepository<T>
{
private readonly IRepository<T> _internalRepo;
public RepositoryCache(IRepository<T> internalRepo)
{
_internalRepo = internalRepo;
}
public IRepository<T> InternalRepo
{
get { return _internalRepo; }
}
}
You will then need to create a type interceptor. You can use the configurable "MatchedTypeInterceptor" provided by StructureMap for this. The interceptor will need to look for your repositories and then figure out what the generic type parameters are. Once it has the type parameters it can declare the type of cache it needs and initialize it. As part of the initialization, it will take the original repository in it's constructor. Then the interceptor will return the completed cache to whatever requested it from the ioc context. Here is the complete sequence inside a test.
This can be moved out into your registry, I just left it all together as an minimal example.
[Test]
public void doTest()
{
MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(
x => x.FindFirstInterfaceThatCloses(typeof (IRepository<>)) != null);
interceptor.InterceptWith(original =>
{
Type closedType = original.GetType()
.FindFirstInterfaceThatCloses(typeof(IRepository<>));
var genericParameters = closedType.GetGenericArguments();
var closedCacheType = typeof(RepositoryCache<>)
.MakeGenericType(genericParameters);
return Activator.CreateInstance(closedCacheType, new[] {original});
});
ObjectFactory.Initialize(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.RegisterInterceptor(interceptor);
});
var test = ObjectFactory.GetInstance<IRepository<int>>();
Assert.That(test is RepositoryCache<int>);
}
I have a Class called Repository for accessing (Read/Write to and from) Database.
The projects that require access to the database create an object of Repository and pass the connection string as a constructor parameter for the repository to work for that particular project.
I have few methods in the Repository that i want to be available only if certain connection strings are passed. I don't want them to be available if some different connection string is passed.
Is there any way I can accomplish that?
I have never used method header technique, can that help? if yes, how can i use it? if no, please let me know if there is any other way to achieve my goal.
Regards.
You could use a factory method pattern to accomplish your goal.
Create a RepositoryFactory class that takes in the connection string and returns a different repository based upon the contents of the string.
public class RepositoryFactory {
public IRepository GetRepository(string connection)
{
if(SomeTestOnConnect(connection))
return new SimpleRepository(connection);
else
return new FullRepository(connection);
}
}
With this when someone wants a repository they call the GetRepository method.
Sort of doing:
if (_connection == "XYZ")
throw new InvalidOperationException();
Is it possible that you could refactor your approach to create a new class:
public class ConnectionInfo
{
public string ConnectionString { get; set; }
public bool IsLimitedAccess { get; set; }
}
Then, in each repository method not allowed, if limited access, return null or throw exception or something?
If you know in advance whether you'll need the extra methods, you could have a base version which doesn't support the extra methods, and a derived type which does. The constructor for the derived type could throw an exception if required information is not provided.
Using a factory method instead of a constructor would allow a base or fancy object to be constructed based upon the passed-in connection string; if you just have one factory method, though, you'll have to typecast the result if you want to use the extra methods.
The best approach may be to have a factory method for each defined type, with a guarantee that it will either return an object that's at least as good as the requested type or throw an exception if it can't. This approach would allow for future expansion in case more further-derived types become available.
If you want to limit the available methods, you could use a pattern like this.
Use the factory to get an instance like this:
var repo = RepositoryFactory.Resovle<IFullRepository>("connection string");
And the code that makes this work is here
public class RepositoryFactory
{
public static T Resovle<T>(string connection) where T: IRepository
{
IRepository instance = new Repository(connection);
return (T)instance;
}
private class Repository : IFullRepository
{
private string _connection;
public Repository(string connection)
{
_connection = connection;
}
public object Get(int id)
{
// select
}
public void Save(object o)
{
// upate
}
public void Create(object o)
{
// create
}
public void CustomMethodOne()
{
// do something specialized
}
public void CustomMethodTwo()
{
// do something specialized
}
}
}
public interface IRepository
{
object Get(int id);
void Save(object o);
void Create(object o);
}
public interface IRepositoryProjectOne: IRepository
{
void CustomMethodOne();
}
public interface IRepositoryProjectTwo: IRepository
{
void CustomMethodTwo();
}
public interface IFullRepository: IRepositoryProjectOne, IRepositoryProjectTwo
{
}
The downsides are, you get an explosion of Interfaces to control what methods are exposed. However, it is possible to cast between the various interfaces, but it avoids having to throw exceptions when a method isn't implemented.
There doesn't seem to be a perfect way to do this however I think your calling method needs to know whether or not it is allowed to write to the Repository as another poster has stated the availability of methods is something that needs to be known at compile time rather than run time.
The solution would be to create two interfaces, one that offers full functionality and one that offers limited functionality.
public interface IRepository : IRead
{
void Write(object o);
}
public interface IRead
{
object Read();
}
Your Repository object then implements the top interface.
public class Repository : IRepository
{
private readonly string _connectionString;
public Repository(string connectionString)
{
_connectionString = connectionString;
}
public object Read()
{
// Do stuff
}
public void Write(object o)
{
// Do stuff
}
}
You can then have a class that determines if the connection string demands a read only repository or not and exposes 2 different methods to return the given type of interface (meaning you need to know the type at compile time).
public static class RepositoryFactory
{
public static bool ConnectionStringIsReadOnly(string connectionString)
{
return connectionString.Contains("user=hacker");
}
public static IRead GetReadOnlyRepository(string connectionString)
{
return new Repository(connectionString);
}
public static IRepository GetRepository(string connectionString)
{
if (ConnectionStringIsReadOnly(connectionString)) throw new ArgumentException(#"Given connectionString is not allowed full repository access", "connectionString");
return new Repository(connectionString);
}
}
You can then consume this as follows, seperating the points where you try to do actions that require full access by checking that you have a version of IRepository or of IRead only.
public class Program
{
public void ConsumeRepository(string connectionString)
{
IRead reader = null;
IRepository repository = null;
if (RepositoryFactory.ConnectionStringIsReadOnly(connectionString))
reader = RepositoryFactory.GetReadOnlyRepository(connectionString);
else
{
repository = RepositoryFactory.GetRepository(connectionString);
reader = repository;
}
object o = reader.Read();
// do something with o
// if allowed then write o to repository
if (repository != null)
{
repository.Write(o);
}
}
}
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.