I have the following class which I pass Entity Framework Model when making an instance of it.
public class TableMapper<TSource>
{
protected IQueryExtractor QueryExtractor { get; set; }
protected string TableAliasPrefix { get; private set; }
public TableMapper(IQueryExtractor queryExtractor, string tableAliasPrefix = null)
{
QueryExtractor = queryExtractor;
TableAliasPrefix = tableAliasPrefix;
}
public IReportRelation GetForeignRelation<TProperty>(Expression<Func<TSource, TProperty>> property)
{
return new ReportRelation
{
Column = GetReportColumn(null, Self, property),
TableName = this.Table(),
TableAlias = this.GetSqlAlias(),
ModelType = typeof(TSource),
QueryExtractor = this.QueryExtractor
};
}
...
...
...
}
I call this above class yet from another class like so
var clientMapper = new TableMapper<Client>(QueryExtractor, "Client");
var = clientMapper.GetForeignRelation(x => x.Id);
Please note that Client
is an Entity Framework 6 model.
From within my GetForeignRelation
method, I set the type of Client
or <TSource>
so I can create a new instance of the TableMapper
class at run time.
Here is what I tried to do in an attempt to create a new instance of it at run time.
var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType);
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias);
But that is giving me an error.
The type or namespace name
RunTimeModel
could not be found (are you missing a using directive or an assembly reference?)
How can I correctly create a new instance of the same class at run time?
You will get the class name of TSource with
typeof(TSource).Name
You should be able to create an instance with:
var instance = Activator.CreateInstance(typeof(TSource));
as long as the type is in the same assembly Other properties can be use to obtain the full namespace
EDIT:
Do this example apply to your scanario? Had to strip down your provided code as I don't know what's behind it all :)
class Program
{
static void Main(string[] args)
{
var test = new TableMapper<A>();
var fr = test.GetForeignRelation();
var type = fr.ModelType;
var newInstance = Activator.CreateInstance(type);
}
}
public class TableMapper<TSource>
{
public TableMapper()
{
}
public ReportRelation GetForeignRelation()
{
return new ReportRelation
{
ModelType = typeof(TSource)
};
}
}
public class ReportRelation
{
public Type ModelType { get; set; }
}
public class A
{
public string Test { get; set; }
public A()
{
Test = "Some string";
}
}
You cannot pass variable to a type parameter
var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType);
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias)
Because RunTimeModel is not a type but a variable. I think you are missing purpose of method which you are using.
You can use the following code to instantiate your generic type :
var RunTimeMapper = Activator.CreateInstance(typeof(TableMapper<>).MakeGenericType(new[] { relationsMapping.ModelType }), new[] { relationsMapping.QueryExtractor, relationsMapping.TableAlias });
However,the return value type for RunTimeMapper is object.I cann't figure out how to cast RunTimeMapper to its actual type.So,it's a little inconvenient to use.
Referer: How to: Examine and Instantiate Generic Types with Reflection
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.