Need advice on naming repositories methods.

S

shapper

Hello,

I am creating a few repositories to work with Entity Framework.
One problem I have is about the naming of the methods. For example:

public interface IAssetRepository {
Asset GetAssetById(Guid id);
Asset GetAssetByName(String name);
IEnumerable<Asset> FindAssets();
IEnumerable<Asset> FindAssetsByCity(String city);
void DeleteAsset(Guid id);
void CreateAsset(Asset asset);
void UpdateAsset(Asset asset);
} // IAssetRepository

Or simpler:

public interface IAssetRepository {
Asset GetAsset(Guid id);
Asset GetAsset(String name);
IEnumerable<Asset> GetAssets();
IEnumerable<Asset> GetAssets(String city);
void Delete(Guid id);
void Create(Asset asset);
void Update(Asset asset);
} // IAssetRepository

This last situation seems cleaner and I use methods that have the same
name but yet different parameters.

I see all kind of examples so I would like to get some advice on how
people usually name the methods.
Or if there is some kind of rule for this ...

Thanks,
Miguel
 
G

Gregory A. Beamer

Hello,

I am creating a few repositories to work with Entity Framework.
One problem I have is about the naming of the methods. For example:

public interface IAssetRepository {
Asset GetAssetById(Guid id);
Asset GetAssetByName(String name);
IEnumerable<Asset> FindAssets();
IEnumerable<Asset> FindAssetsByCity(String city);
void DeleteAsset(Guid id);
void CreateAsset(Asset asset);
void UpdateAsset(Asset asset);
} // IAssetRepository

Or simpler:

public interface IAssetRepository {
Asset GetAsset(Guid id);
Asset GetAsset(String name);
IEnumerable<Asset> GetAssets();
IEnumerable<Asset> GetAssets(String city);
void Delete(Guid id);
void Create(Asset asset);
void Update(Asset asset);
} // IAssetRepository

This last situation seems cleaner and I use methods that have the same
name but yet different parameters.

I see all kind of examples so I would like to get some advice on how
people usually name the methods.
Or if there is some kind of rule for this ...


Here is my argument against this type of coding

Get(Guid id)
Get(string name)
GetAll(string city)
GetAll()

What if someone else had coded?

Get(Guid id)
Get(string name)
GetAll(string lastName)
GetAll()

Suddenly, you have two meanings of

GetAll(string s)

depending on who coded. If I am going generic, I need a standard. Perhaps
the generic interface is Get() and GetById().

Get()
GetById(int id)

But you end up standardizing primary keys here, as the following leads to
issues:

GetById(Guid guid)

You could, however, genericize the GUID keys with

GetByGuid(Guid guid)

Just rambling now.;-)


--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
S

shapper

GetByGuid(Guid guid)

What? By that I could have:

GetByString(String name)
GetByString(String city)

That does not make much sense.

I could do something else which would be:

void Delete(Guid id);
void Create(Asset asset);
void Update(Asset asset);

These are the basic. Then I could create "Specifications" and do the
following:

Asset GetAsset(Some Specification);
IEnumerable<Asset> GetAssets(Some Specification);

Being specifications something like IDEqualTo(...), NameEqualTo(...)

I read about this somewhere but to be honest I am not sure how to
implement it or if it is even a good idea.
 
G

Gregory A. Beamer

What? By that I could have:

GetByString(String name)
GetByString(String city)

That does not make much sense.

That is also not what I am suggestion ... at all.

I am stating that you can, if you use both IDENTITY and GUID have two
methods:

GetByID(int id)
GetByGuid(Guid id)

If you want to do some custom pulls on a table, it is best to use the
format:

GetBy{FieldName}(string val)

I could do something else which would be:

void Delete(Guid id);
void Create(Asset asset);
void Update(Asset asset);

This is fairly standard for a repository. But you are typing the
repository explicitly. You can actual move the Create, Update or even
encapsulate both in a Save() method, in a generic repository.

As an example, I did a few experiments with a generic repository. here
are some links to blog entries for LINQ to SQL:

http://bit.ly/NzEGP
http://bit.ly/10MkRX
http://bit.ly/FZEd
http://bit.ly/McWzt

NOTE: The entire generic repository was a bit of R&D work. One of the
requirements was the ability to easily pass the objects to a Java
client, so POCO was preferable. I found that a DataSet and a single LINQ
table per DBML worked best to avoid creating additional objects for my
primary key. EF is becomming a possibility in .NET 4.0, as you can use
POCO (plain old CLR objects), which is not a possibility at the time the
blog entries were written.

These are the basic. Then I could create "Specifications" and do the
following:

Asset GetAsset(Some Specification);
IEnumerable<Asset> GetAssets(Some Specification);

Being specifications something like IDEqualTo(...), NameEqualTo(...)

I read about this somewhere but to be honest I am not sure how to
implement it or if it is even a good idea.

If you adhere to interfaces, the standard repository followed by many
will look something like this;

public interface IRepository
{
Object[] GetAll();
Object GetById();
void Delete(Object o);
void Save(Object o);
}

With LINQ to SQL, in a generic way, I had this:

public interface IRepository<T> where T : class
{
List<T> All();
List<T> FindAll(Func<T, bool> exp);
List<T> Where(Func<T, bool> exp);

T Single(Func<T, bool> exp);
T First(Func<T, bool> exp);
T Last(Func<T, bool> exp);
T Save(T entity);

T Insert(T entity);
void Destroy(T entity);
void Delete(T entity);
void UnDelete(T entity);

void MarkForDeletion(T entity);
T CreateInstance();

/// <summary>Persist the data context.</summary>
void SaveAll();
}

I don't like the idea of having to code multiple interfaces, like so:

public interface IPersonRespository
{
Person() GetAllPersons();
Person GetPersonById(Guid id);
}

public interface IOrderRepository
{
Order() GetAllOrders();
Order GetOrderById(Guid id);
}

With generics, I can reduce this to one IRepository. I can then code the
specific stuff on specific repository interfaces, like:

public interface IPersonRepository
{
Person() GetByLastName(string lastName);
Person() GetByFirstName(string firstName);
}

In my original post, I was focusing on how, if a database is
standardized to either IDENTITY or GUID for primary key, you can
genericize the DAL greatly. Then you do not have to rely on Intellisense
to code something like this:

public void ProcessOrderByPerson(int orderid)
{
Order o = OrderRepository.GetById(orderid);
int personId = o.PersonId;
Person p = PersonRepository.GetById(personId);
}

I would not use the word person here. It would be Employee for the sales
person and Customer for the customer, etc. The idea here is GetById()
has a universal meaning that is consistent.

You ultimately have to decide what works for you, but if you use GetById
or perhaps GetById and GetByGuid, you can use generics and save a lot of
coding. If you are using a code generator, then it is not as necessary.

Hope this makes sense.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 

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