I am wondering if anyone has any good tutorials(or maybe even a library that is already made and well documented) on making a generic repository.
I am using currently linq to sql but it might change so I don't know if you can make a generic repository that would take little to no changes if I would say switch to entity framework.
Thanks
I think I should also add why I want a generic repository. The reason is in my database I have like corporate tables(users who's subscriptions are paid by someone else) and individual tables(people who find my site through google or whatever and pay for their own subscription)
But I will have 2 very similar tables. For instance I have 2 settings tables one for corporate users and one for the individuals.
Now since they are 2 different tables I need 2 different insert methods as I am inserting it into 2 different tables and at this current time only one field is different(that is the PK).
So now I need all these duplicate methods and I don't want that. Maybe what I have in my database is could be considered as a design flaw(and maybe it is) but one of the reasons behind this was if needed I can break up my database into 2 different databases very easy and I am not going to change my design anytime soon.
Here is my answer to another question of the same type. Hope it helps:
Advantage of creating a generic repository vs. specific repository for each object?
Edit:
It sounds like you want to treat two concrete types as one logical type. To do that, first define the logical type:
public interface ISubscription
{
// ...
}
Then, define the concrete types as part of your data model (interfaces would be implemented in another partial class):
[Table("CorporateSubscription")]
public partial class CorporateSubscription : ISubscription
{
}
[Table("IndividualSubscription")]
public partial class IndividualSubscription : ISubscription
{
}
Next, define the repository which operates on the logical type:
public interface ISubscriptionRepository
{
CorporateSubscription GetCorporate(string key);
IndividualSubscription GetIndividual(int userId);
IEnumerable<ISubscription> ListAll();
IEnumerable<CorporateSubscription> ListCorporate();
IEnumerable<IndividualSubscription> ListIndividual();
void Insert(ISubscription subscription);
}
Finally, implement the interface by using both tables:
public class SubscriptionRepository : ISubscriptionRepository
{
private readonly YourDataContext _dataContext;
public SubscriptionRepository(YourDataContext dataContext)
{
_dataContext = dataContext;
}
#region ISubscriptionRepository
public CorporateSubscription GetCorporate(string key)
{
return _dataContext.CorporateSubscriptions.Where(c => c.Key == key).FirstOrDefault();
}
public IndividualSubscription GetIndividual(int userId)
{
return _dataContext.IndividualSubscriptions.Where(i => i.UserId == userId).FirstOrDefault();
}
public IEnumerable<ISubscription> ListAll()
{
return ListCorporate()
.Cast<ISubscription>()
.Concat(ListIndividual().Cast<ISubscription>());
}
public IEnumerable<CorporateSubscription> ListCorporate()
{
return _dataContext.CorporateSubscriptions;
}
public IEnumerable<IndividualSubscription> ListIndividual()
{
return _dataContext.IndividualSubscriptions;
}
public void Insert(ISubscription subscription)
{
if(subscription is CorporateSubscription)
{
_dataContext.CorporateSubscriptions.InsertOnCommit((CorporateSubscription) subscription);
}
else if(subscription is IndividualSubscription)
{
_dataContext.IndividualSubscriptions.InsertOnCommit((IndividualSubscription) subscription);
}
else
{
// Forgive me, Liskov
throw new ArgumentException(
"Only corporate and individual subscriptions are supported",
"subscription");
}
}
#endregion
}
Here is an example of an insert. Don't get too wrapped up in the presenter class; I just needed a situation in which subscriptions would be created based on a flag:
public class CreateSubscriptionPresenter
{
private readonly ICreateSubscriptionView _view;
private readonly ISubscriptionRepository _subscriptions;
public CreateSubscriptionPresenter(
ICreateSubscriptionView view,
ISubscriptionRepository subscriptions)
{
_view = view;
_subscriptions = subscriptions;
}
public void Submit()
{
ISubscription subscription;
if(_view.IsCorporate)
{
subscription = new CorporateSubscription();
}
else
{
subscription = new IndividualSubscription();
}
subscription.Notes = _view.Notes;
_subscriptions.Insert(subscription);
}
}
Great Linq to Sql resources:
A t4 template that by generates exactly what is created by default, but can be fully customised.
http://l2st4.codeplex.com/
Using Linq to Sql for a multi tier application. It has a GenericObjectDataSource which I have found very handy
http://multitierlinqtosql.codeplex.com
Search all properties of an IQueryable with one single search
http://naspinski.codeplex.com/