Reputation: 362
I have a class say 'AllInvoices', the structure of which is as below :
public class ActiveInvoices
{
public string InvoiceId { get; set; }
public string InvoiceIssueDate { get; set; }
public string InvoiceTransactionDate { get; set; }
public string InvoiceExpiryDate { get; set; }
}
The mapping class for Entity ActiveInvoices is
public class ActiveInvoicesMap : ClassMap<ActiveInvoices>
{
public ActiveInvoicesMap()
{
Id(x => x.InvoiceId);
Map(x => x.InvoiceIssueDate);
Map(x => x.InvoiceTransactionDate);
Map(x => x.InvoiceExpiryDate);
}
}
Now with this entity I search for Active Invoices in database with the following class
public class SearchInvoices
{
public readonly IRepository<ActiveInvoices> latestActiveInvoicesRepository;
public SearchInvoices(IRepository<ActiveInvoices> activeInvoicesRepository)
{
latestActiveInvoicesRepository = activeInvoicesRepository;
}
public List<ActiveInvoices> GetActiveInvoices()
{
var listOfActiveInvoices = latestActiveInvoicesRepository.GetAll();
return listOfActiveInvoices;
}
}
To Search Active Invoices I call the Search Class method 'GetActiveInvoices()' from a workflow class which looks like below :
public class CurrentWorkFlow
{
public void GetActiveInvoices()
{
var invoiceSearch = new SearchInvoices(IRepository <ActiveInvoices> repository);
}
}
Now the issue in hand is that I need to make class 'SearchInvoices' generic to support all other possible types that i would create like 'ExpiredInvoices', 'ArchivedInvoices', 'FutureInvoices' etc and not just only for type 'ActiveInvoices'. These new types may or may not have the same structure as 'ActiveInvoices'. I have tried to use dynamic but thought of asking experts around here if they have any better ideas to implement the required functionality in most optimized generic manner.
Regrets for being very detailed and lengthy in asking but i thought to include as many details as i can. Hope it goes well with you folks.
Upvotes: 1
Views: 328
Reputation: 6430
Couldn't you make a generic repository like this? -
interface IDomain{
}
class ExpiredInvoices: IDomain{
}
class ActiveInvoices: IDomain{
}
interface IRepository{
}
class Repsoitory: IRepository {
public static IList<T> Get<T>() where T: IDomain //default one
{
using (ISession session = OpenEngineSession())
{
return session.Query<T>().ToList();
}
}
public static IList<T> Get<T>(Expression<Func<T, bool>> expression) where T: IDomain // overloaded get with linq predicate
{
using (ISession session = OpenEngineSession())
{
return session.Query<T>().Where(expression).ToList();
}
}
}
Then use it like -
var repo = // get IRepository
var activeInvoices = repo.Get<ActiveInvoices>();
var expiredInvoices = repo.Get<ExpiredInvoices>();
EDIT: As Repository cannot be changed, suggested by OP
If you cannot change the repository, then I would suggest making the search service interface
dependent, rather than concrete
class -
interface IInvoice{
}
class ExpiredInvoices: IInvoice{
}
class ActiveInvoices: IInvoice{
}
public class SearchInvoices
{
public readonly IRepository<IInvoice> latestActiveInvoicesRepository;
public SearchInvoices(IRepository<IInvoice> activeInvoicesRepository)
{
latestInvoicesRepository = activeInvoicesRepository;
}
public List<T> GetActiveInvoices<T>() where T: IInvoice
{
var listOfActiveInvoices = latestActiveInvoicesRepository.GetAll();
return listOfActiveInvoices;
}
}
Then call like -
var ss = new SearchService(IRepository <ActiveInvoices> repository);
var items = ss.GetActiveInvoices<ActiveInvoices>();
Or,
public class SearchInvoices<T> where T: IInvoice
{
public readonly IRepository<T> latestActiveInvoicesRepository;
public SearchInvoices(IRepository<T> activeInvoicesRepository)
{
latestInvoicesRepository = activeInvoicesRepository;
}
public List<T> GetActiveInvoices()
{
var listOfActiveInvoices = latestActiveInvoicesRepository.GetAll();
return listOfActiveInvoices;
}
}
then call like -
var ss = new SearchService<ActiveInvoices>(IRepository <ActiveInvoices> repository);
var items = ss.GetActiveInvoices();
Whichever suits you.
Upvotes: 2