CSLA Day 3 – Linq to SQL in CSLA

Note: This is the work thoughts when I first start CSLA coding. Right now I actually pass DTO between my DAL and BO, and the technique describe in this post is not in my project because it is too tightly coupled.

We can treat CSLA as a security and validation warper for Domain Object. The new CSLA 3.5 implemented (Linq to SQL) in BO’s Fetch.

// get project data
var data = (from p in ctx.DataContext.Projects
where p.Id == criteria.Value
select p).Single();
LoadProperty<Guid>(IdProperty, data.Id);
LoadProperty<string>(NameProperty, data.Name);

What I want to do is to encapsulate those LinQ syntax to IDataContext. So the BO developer doesn’t have to know how to write it.

interface ITrainingDataContext
{
Trainee GetTraineeById(int id);

}

partial class TrainingDataContext : ITrainingDataContext
{

public Trainee GetTraineeById(int id)
{
return Trainees.Single(c => c.Trainee_ID == id);
}

}

In BO:

public TrainingDataContext dtx;

private void DataPortal_Fetch(Criteria criteria)
{

DalLinq.Trainee data = dtx.GetTraineeById(criteria.TraineeId);

_traineeId = data.Trainee_ID;
_sessionId = data.Session_ID;
_givenNames = data.Given_Names;
_lastName = data.Last_Name;

The benefit of this change is, we can UnitTest GetTraineeById before create BO.

Next, I want to remove those setting fields junk by enable CSLA BO holding LinQ entities, as other developer want. But due to the serialization limitation, I couldn’t do this directly. Followed  WinSpace’s idea, I made CSLA BO hold serialized object instead. Then the code becomes:

private SerializableEntity<Gain.DalLinq.Trainee> _data;

public string GivenNames
{
get
{
CanReadProperty(“GivenNames”, true);
return _data.Entity.Given_Names;
//                return _givenNames;
}
set
{
CanWriteProperty(“GivenNames”, true);
if (value == null) value = string.Empty;
if (!_data.Entity.Given_Names.Equals(value))
{
_data.Entity.Given_Names = value;

PropertyHasChanged(“GivenNames”);
}
}
}

private void DataPortal_Fetch(Criteria criteria)
{

TrainingDataContext dtx = new TrainingDataContext();
_data =  dtx.GetTrainee(criteria.TraineeId);

It looks pretty good for now. To test DataProtal_Fetch, I need to mock ITrainingDataContext, tried to inject DataContext in constructor but failed, error is ‘DataContext is not marked as is not marked as serializable’, exact same as Rocky described before.

So it turns out I can only do like this:

private void DataPortal_Fetch(Criteria criteria)
{
DataPortal_Fetch(criteria, new TrainingDataContext());
}

public void DataPortal_Fetch(Criteria criteria, ITrainingDataContext dtx)
{

_data =  dtx.GetTrainee(criteria.TraineeId);

Criteria has to be made public as well.

But, do I have to unit test DataPortal_Fetch? Maybe in BO, we should focus more on security and validation test only?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s