Reputation: 53
I'm trying to dynamically generate reports and email them to the appropriate users is this possible or can does the compiler need the type before runtime.
static void Main(string[] args) {
ArrayList ReportsTypes = new ArrayList();
ReportsTypes.Add(typeof(AgentPPL));
foreach(Type t in ReportsTypes) {
InitilizeReports<t>(); // <- Error
}
}
static void InitilizeReports<T>() where T : new() {
T r = new T();
IReportDocument rd = (IReportDocument)r;
rd.DocumentName = "SomeReport";
ExportReport(rd);
}
What I'd really like to do is grab a string out of the database and convert the string to a type but I doubt thats possible but what about creating an array of types like in my example what am doing wrong here. Any help is much appreciated I've been spinning my wheels for a while just to get my templates working.
Upvotes: 1
Views: 226
Reputation: 17848
You can use one of the following approaches:
ReportGenerator generator = new ReportGenerator();
// 1. Invoke method with single parameter
foreach(Type t in ReportsTypes) {
generator.InitilizeReportsByType(t);
}
// 2. Make and invoke generic method without parameter via reflection
MethodInfo mInfo = typeof(ReportGenerator).GetMethod("InitilizeReportsGeneric");
foreach(Type t in ReportsTypes) {
MethodInfo genericMethod = mInfo.MakeGenericMethod(new Type[] { t });
genericMethod.Invoke(generator, new object[] { });
}
public class ReportGenerator {
public void InitilizeReportsByType(Type type) {
IReportDocument reportDocument = (IReportDocument)Activator.CreateInstance(type);
//...
}
public void InitilizeReportsGeneric<T>() where T : IReportDocument, new() {
T reportDocument = new T();
//...
}
}
Note, that T reportDocument = new T()
are equal to Activator.CreateInstance(type)
because it is only compiler syntax sugar.
Upvotes: 1
Reputation: 1685
You could modify the code just a bit and use reflection instead:
static void Main(string[] args)
{
ArrayList ReportsTypes = new ArrayList();
ReportsTypes.Add(typeof(AgentPPL));
foreach (Type t in ReportsTypes)
{
InitilizeReports(t);
}
}
static void InitilizeReports(Type t)
{
var r = Activator.CreateInstance(t);
AgentPPL rr = new AgentPPL();
IReportDocument rd = (IReportDocument)r;
rd.DocumentName = "SomeReport";
ExportReport(rd);
}
Upvotes: 0
Reputation: 65441
You can create an instance of a class from a string as follows:
Type reportType = Type.GetType("ClassName.Including.Namespace");
IReportDocument report = (IReportDocument)Activator.CreateInstance(reportType);
Upvotes: 0
Reputation: 34707
You can convert a string to a Type with Type.GetType(string typeName):
Type intType = Type.GetType("System.Int32");
Upvotes: 0