The mentalist Coder
The mentalist Coder

Reputation: 362

Fluent Nhibernate : How to make Search Class Generic in best possible way

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

Answers (1)

brainless coder
brainless coder

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

Related Questions