Reputation: 1317
I'm using structure map to automatically inject a DataContext into my Repository constructor. I'm given a name (e.g. "Project1") and I need to dynamically create an instance of the Repository for project.
I'm using a standard naming convention, so I know it's "Project1DataContext". I've managed to create an instance of my Project1DataContext using reflection, but it's an object type. The problem is I need to pass a Project1DataContext object into my Repository to create an instance of it. How can I do this using reflection? Would it be possible to cast the object through some means?
Assembly myDataContextAssembly = typeof(SomeTypeInTheAssembly).Assembly;
Type dataContextType = myDataContextAssembly.GetType(ProjectName + "DataContext");
object dataContext = Activator.CreateInstance(dataContextType);
// I need to cast the data context here
IRepository<Project1DataContext> = new Repository<Project1DataContext>(dataContext)
In the mean time, I will use an if statement, but this is not a viable solution if I have 100+ projects. I need to do this using reflection and ideally having structure map determine the types and injecting them for me.
Upvotes: 2
Views: 755
Reputation: 3635
Given what I understand from the information provided, you want to cast the dataContext object to its real type before you pass that type to the IRepository and Repository generic classes. Which means that you want to make them concrete. You can make them concrete during runtime but not via passing a Type object as a generic argument. Also, you can't rely on generic type inference here because that is only done at compile time.
I will suppose that your method returns an IRepository or Respository (without generic parameters).
Here is what you need to do: Create a concrete type for Repository<> using dataContextType and then use that concrete type to create a Repository object that you cast to Repository and then return it.
Assembly myDataContextAssembly = typeof(SomeTypeInTheAssembly).Assembly;
Type dataContextType = myDataContextAssembly.GetType(ProjectName + "DataContext");
Type concreteRepositoryType = typeof(Generic<>).MakeGenericType(dataContextType);
Repository repository = (Repository)System.Activator.CreateInstance(concreteRepositoryType);
return repository;
Upvotes: 1