简体   繁体   中英

Is there a way to find an interface implementation based on a generic type argument?

I have a data access library that has a few classes that all implement the same interface, which has a generic type parameter:

public interface IGetByCommonStringRepository<TEntity>
{
    TEntity GetByCommonStringColumn(string commonString);
}

public class Repository1<Entity1> : IGetByCommonStringRepository<Entity1>
{
    public Entity1 GetByCommonStringColumn(string commonString)
    {
        //do stuff to get the entity
    }
}

public class Repository2<Entity2> : IGetByCommonStringRepository<Entity2>
//...and so on 

Rather than forcing consumers of this library to instantiate one of the four repository classes separately for each <TEntity> , I am hoping that there's some way that I can create a static method in a "helper/utility" class in the same assembly that will be able to discern which implementation to instantiate, create an instance, and execute the GetByCommonStringColumn method. Something like...

public static TEntity GetEntityByCommonStringColumn(string commonString) where TEntity : class
{
    IGetByCommonStringRepository<TEntity> repository = 
        DoMagicalReflectionToFindClassImplementingIGetByCommonString(typeof(TEntity));
    //I know that there would have to an Activator.CreateInstance() 
    //or something here as well.
    return repository.GetByCommonStringColumn(commonString) as TEntity;
}

Is anything like this possible?

That example still needs further fixing.. For each repository it is missing a constraint. For each public (right now it is invalid private) method it is also missing a functional body.. For that interface method it requires a generic argument.

Then try, or play around, if I understood you right:

 public static TEntity clr_bloat_reflected_msdn_method<TEntity>(string commonString) where TEntity : class { Assembly a = Assembly.GetExecutingAssembly(); foreach (Type t in a.GetTypes()) if (!t.IsAbstract && typeof(IGetByCommonStringRepository<TEntity>).IsAssignableFrom(t)) return ((IGetByCommonStringRepository<TEntity>)Activator.CreateInstance(t)).GetByCommonStringColumn(commonString); return null; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM