views:

68

answers:

3

I'm implementing some naive searching in my application, and searches will take place on a couple of different object types (Customer, Appointment, Activity, etc.). I'm trying to create an interface that will have types that are searchable. What I'd like to do is something like this:

public interface ISearchable
{
    // Contains the 'at a glance' info from this object 
    // to show in the search results UI
    string SearchDisplay { get; }

    // Constructs the various ORM Criteria objects for searching the through 
    // the numerous fields on the object, excluding ones we don't want values 
    // from then calls that against the ORM and returns the results
    static IEnumerable<ISearchable> Search(string searchFor);
}

I already have a concrete implementation of this on one of my domain model objects, but I'd like to extend it to others.

The problem is obvious: you can't have static methods on an interface. Is there another prescribed method to accomplish what I'm looking for, or is there a workaround?

A: 

I don't really know the solution for C#, but according to this question, Java seems to have the same problem and the solution is just to use a singleton object.

Platinum Azure
+2  A: 

Interfaces really specify the behavior of an object, not a class. In this case, I think one solution is to separate this into two interfaces:

public interface ISearchDisplayable
{
    // Contains the 'at a glance' info from this object 
    // to show in the search results UI
    string SearchDisplay { get; }
}

and

public interface ISearchProvider
{
    // Constructs the various ORM Criteria objects for searching the through 
    // the numerous fields on the object, excluding ones we don't want values 
    // from then calls that against the ORM and returns the results
    IEnumerable<ISearchDisplayable> Search(string searchFor);
}

An instance of ISearchProvider is an object that does the actual searching, while an ISearchDisplayable object knows how to display itself on a search result screen.

Matthew Flaschen
This would require me to have an existing instance of the class(es) I want to search against. Which I won't have any of at search time.
SnOrfus
@SnOrfus, yes, I am suggesting you change your design so that you call `Search` on an instance, rather than a class.
Matthew Flaschen
+1: I think I might combine this with mquander's suggestion of creating a SearchProvider helper class.
SnOrfus
A: 

It looks like you will need at least one other class, but ideally you would not need a separate class for each ISearchable. This limits you to one implementation of Search(); ISearchable would have to be written to accommodate that.

public class Searcher<T> where T : ISearchable
{
    IEnumerable<T> Search(string searchFor);
}
Khyad Halda