Generics n-tier design question

R

russ

Hi,

We have stumbled across an issue using the type safe collection
System.Collections.ObjectModel.Collection <T> to retrieve data from our
data layer.

Say we have a customer object and want to get a type safe collection of
all customers who have spend = X
Within our datalayer we would currently have the following method

public static ArrayList GetCustomersWithSpend(Type type, double spend)
{
// use custom or mapper here
return ObjectSpace.GetCollection(type,"where spend =" +
spend.ToString());
}

However, say we wanted to use a type safe generic collection I guess we
would use this;

public static
System.Collections.ObjectModel.Collection<Customer>(double spend)
{
}

But this would break the n-tier seperation as our datalayer now knows
about the Customer type.

I guess we could still return an ArrayList from the datalayer and then
create the type safe collection in the business tier using the
ArrayList.

Does anyone have any thoughts on this?

Cheers

Russ
 
N

Nicholas Paldino [.NET/C# MVP]

Russ,

The thing is, in a logical sense, you are already breaking your n-tier
separation in your data layer. If you have a method named
"GetCustomersWithSpend", then obviously you are going to return customers,
and not something else. If anything, this is a business layer function
which in turn will call the data layer.

If you really want to keep your types out of the data layer, then return
an ArrayList, and then have a proxy/wrapper in the business side, which does
this:

// In business layer.
public static IList<Customer> GetCustomersWithSpend(Type type, double spend)
{
// Make the call to the data layer.
ArrayList objects = DataLayer.GetCustomersWithSpend(type, spend);

// Convert to an IList implementation:
List<Customer> retVal = new List<Customer>(objects.Count);

// Cycle through and add the item.
foreach (object o in objects)
{
// Add to the arraylist.
retVal.Add((Customer) o);
}

// Return.
return retVal;
}

You should use ICollection<T> instead of Collection<T>, since it will be
easier to swap out later (and there is nothing on the implementation which
isn't offered through the interface). Additionally, IList extends
ICollection<T>, and it offers an indexer, as well as being able to support
data binding easier. Because of this, I returned IList<Customer>.

Hope this helps.
 
R

russ

Many thanks for the reply Nicholas,

I agree that we shouldn't really have the GetCustomersBySpend method
but we struggled with how to get custom collections created using SQL
from the datalayer without creating static methods like
GetCustomersBySpend.

Your solution looks like the best option though :)
 
J

Joanna Carter [TeamB]

"russ" <[email protected]> a écrit dans le message de (e-mail address removed)...

| We have stumbled across an issue using the type safe collection
| System.Collections.ObjectModel.Collection <T> to retrieve data from our
| data layer.

| However, say we wanted to use a type safe generic collection I guess we
| would use this;
|
| public static
| System.Collections.ObjectModel.Collection<Customer>(double spend)
| {
| }

We do the following :

We would create a List<Customer> in the data layer

List<T> also implements IList

The method returns an IList

We assign the result of the method call, casting it back to the
List<Customer>

Joanna
 
J

Joanna Carter [TeamB]

"Joanna Carter [TeamB]" <[email protected]> a écrit dans le message de
news: (e-mail address removed)...

| We do the following :

Better still, parameterise the retrieval method :

public List<T> GetList<T>()
{
...
}

This then allows the following syntax in calling :

List<Customer> = DataLayer.GetList<Customer>();

Joanna
 
M

Michael S

Nicholas Paldino said:
Because of this, I returned IList<Customer>.

Hope this helps.

Thanks Nicholas.

From now on I will also start using IList<T> and not return implementing
classes.
I'm not much for serious data abstraction, but this makes a lot of sense to
me.

Happy Coding
- Michael S
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top