Reputation: 8211
I have a generic interface:
public interface IGeneric<T>
{
Method1(T t);
Method2(T t);
}
Using following piece of code, I create an instance of IGeneric<T>
based on an entity type, dynamically:
var entityType = entity.GetType();
var genericType = typeof(IGeneric<>).MakeGenericType(entityType);
var result = Activator.CreateInstance(genericType);
For example if my entity is an Order
the result will be IGeneric<Order>
.
Now, how can I call the result's methods, for example I want to call Method1()
:
result.Method1();
But the Method1()
isn't accessible.
Upvotes: 0
Views: 749
Reputation: 15787
I think that any IoC container, framework that knows how to resolve types, is something that you are looking for. First open generic types can be registered, then their inmplementations can be resolved.
According to your code block I suggest you use the following approach. It uses Activator
to create an instance of Repository<T>
that inherits IRepository<T>
. IRepository
interface provides an ability to cast result
to the non-generic type an invoke Insert
method without reflection.:
public class GenericInterfaceTests
{
[Fact]
public void IncertsStringEntity()
{
// Arrange.
var entity = "100500";
var entityType = entity.GetType();
var genericType = typeof(Repository<>).MakeGenericType(entityType);
var result = Activator.CreateInstance(genericType);
// Act.
(result as IRepository).Insert(entity);
// Assert.
result.Should().BeOfType<Repository<string>>();
var repository = result as Repository<string>;
repository.DataSource.Should().Contain(entity);
}
[Fact]
public void InsertsIntegerEntity()
{
// Arrange.
var entity = 100500;
var entityType = entity.GetType();
var genericType = typeof(Repository<>).MakeGenericType(entityType);
var result = Activator.CreateInstance(genericType);
// Act.
(result as IRepository).Insert(entity);
// Assert.
result.Should().BeOfType<Repository<int>>();
var repository = result as Repository<int>;
repository.DataSource.Should().Contain(entity);
}
}
public interface IRepository<TEntity>
{
void Insert(TEntity entity);
}
public interface IRepository
{
void Insert(object entity);
}
public class Repository<TEntity> : IRepository<TEntity>, IRepository
{
public List<TEntity> DataSource { get; set; }
public Repository()
{
DataSource = new List<TEntity>();
}
public void Insert(TEntity entity)
{
DataSource.Add(entity);
}
void IRepository.Insert(object entity)
{
Insert((TEntity)entity);
}
}
Upvotes: 0
Reputation: 22481
The following sample shows how to call methods that are located in a generic interface:
using System;
public interface IMyInterface<T>
{
T Method1(T input);
}
public class MyImpl : IMyInterface<int>
{
public int Method1(int input)
{
return input * 2;
}
}
public class Test
{
public static void Main()
{
// Concrete type that implements the interface
Type implType = typeof(MyImpl);
// Type of generic interface
Type genType = typeof(IMyInterface<>);
// Interface for int
Type concType = genType.MakeGenericType(typeof(int));
// Create instance
object inst = Activator.CreateInstance(implType);
// Retrieve member that you want to call
var member = concType.GetMethod("Method1");
// Invoke member on instance
var result = member.Invoke(inst, new object[] { 123 });
Console.WriteLine("{0} --> {1}", 123, result);
}
}
You can run and edit the sample here.
Upvotes: 1