IRepository Code
This is by request from Frank Mao, he was wanting me to post up the code I am using for IRepository<T> so here it is:
public interface IRepository<T>
{
//IList<T> FetchList();
ICriteria CreateCriteria();
T Get(object id);
void Load(T obj, object id);
void Delete(T entity);
void DeleteAll();
void DeleteAll(DetachedCriteria where);
T Save(T entity);
T SaveOrUpdate(T entity);
T SaveOrUpdateCopy(T entity);
void Update(T entity);
long Count(DetachedCriteria criteria);
long Count();
bool Exists(DetachedCriteria criteria);
bool Exists();
IList<T> FindAll(DetachedCriteria criteria, params Order[] orders);
IList<T> FindAll(Order order, params ICriterion[] criteria);
IList<T> FindAll(Order[] orders, params ICriterion[] criteria);
T FindFirst(params Order[] orders);
T FindFirst(DetachedCriteria criteria, params Order[] orders);
T FindOne(params ICriterion[] criteria);
T FindOne(DetachedCriteria criteria);
ProjT ReportOne<ProjT>(ProjectionList projectionList);
ProjT ReportOne<ProjT>(DetachedCriteria criteria, ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(DetachedCriteria criteria, ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, DetachedCriteria criteria, ProjectionList projectionList, params Order[] orders);
}
}
I should note that this is a slightly modified version of IRepository that I got from the UnitOfWork tutorial code that is posted here: http://hibernatingrhinos.googlecode.com/svn/trunk/UnitOfWork/src/NHibernateRepository/
Very thoughtful! Thanks Ryan.
I see the benefits from CSLA’s ObjectFactory. Looks like this extra layer between BO and Repository at least cut BO code much lesser. But this is based on the GenericFactory should be very general.
Have you tried new Rhino AAA syntax ? The code on your googlecode still using record and playback style.
With the Repository returning BO instead of DTO, you can’t get rid of “Activator.CreateInstance(typeof(BO), true)” in your mock arrangement. This syntax itself is against the OCP rule, and most ALT.net guys don’t like it.
Frank,
Thanks for the response. I am using the new AAA syntax in my tests of the factories, at least I think I am. I just checked that code in yesterday. I haven’t converted the other tests yet to the AAA style.
With regards to: Activator.CreateInstance(typeof(BO), true)
You are referring to the Create() method in the factories right?
Another question for you then on DTO’s how do you load your BO from your DTO is this automated or just follows the old LoadProperty() method?
I don’t think we can do any improvement for the create() in factories, that’s CSLA magic, same as the one in setting exception to mock repository, which I really don’t like it.
We do not ‘automated’ transfer data, but are using datamapper to manually load data from DTO into BO, code is less, just one line, but performance might be worse than LoadProperty(). I saw a post talking about to allow developer to set a ‘ignore’ flag or something, to skip validation and security to fast load data.
Could you share some of your datamapper code? Is this something you have to do in every class like:
BO.Name = DTO.Name;
or does the datamapper do that for you?
Here are two instance methods we created. Our DTO is almost identical to BO, but without those SmartDates and ChildProperties. So DAL knows anything about BL.
protected OrganizationDTO BuildDTO()
{
var result = new OrganizationDTO();
// DataMapper moves property values with the same name from source to target
DataMapper.Map(this, result, OrganizationBO.IgnoreColumnListForDataMapping);
return result;
}
protected OrganizationBO LoadDataFromDTO(OrganizationDTO data)
{
// Id has no setter, we set it directly.
LoadProperty(IdProperty, data.Id);
DataMapper.Map(data, this,IgnoreColumnListForDataMappingWithPK);
// Reset flags dataMapper has messed up. No need to do this if the new ‘ignore’ feature came out.
this.MarkClean();
this.MarkOld();
ValidationRules.CheckRules();
return this;
}
Is the DataMapper object home grown or is it from somewhere else? I would really like to take a look at it. I don’t think it would be difficult at all to make the implementation I have work with a DTO’s and a DataMapper, I just don’t know / haven’t seen a datamapper before.
It’s from Csla.Data.DataMapper.
By the way, the new feature I mentioned is called ‘ByPassPropertyChecks’. Suggested by
http://forums.lhotka.net/forums/thread/25381.aspx
Looks it’s done. http://lhotka.net/cslabugs/edit_bug.aspx?id=70
But not sure it’s in 3.5.2 or 3.6 beta. Maybe both?
I just tried, this new BypassPropertyChecks is only available for 3.6
so my datamapper can be:
using (this.BypassPropertyChecks){
DataMapper.Map(this, result, IgnoreColumnListForDataMapping);
}
It is making better sense now, I had actually just stumbled across that Csla had a datamapper before I left the office. But your posts make good sense and help me put together a bigger picture in my head. I am headed out of town for a few days but I will look into this more when I return. I really enjoy the conversation we are having/starting on Csla with altdotnet too.