0

I have a number of classes with the following pattern:

namespace MyCompany.MyApplication.ReportingClasses
{
public class ReportingClassName
{
    public string HTMLReportString {get; private set;}

    ReportingClassName()
    {
        // Use linq to generate report;
        // Populate gridview, pass object to function which returns HTMLString;
        // set HTMLReportString property;
    }

}
}

Each class holds a different linq query based on the report. I want to load the class dynamically from a list of reports in a drop down box. I store the AsseblyQualifiedName as well as a display name to populate the DDL. I have used reflection based on the posts that I have seen, but I can't seem to perform what I would like;

string myAssembly = "AssemblyName"; // This is static;
string myClass = "AssemblyQualifiedName"; // This value from DDL;
var myObject = Activator.CreateInstance(AssemblyName, AssemblyQualifiedName);

string propertyValue = myObject.HTMLReportString;

"UpdatePanelID".InnerHTML = propertyValue;

Is what I am trying to accomplish possible?

2
  • 1
    The first four lines are straightforward - change var myObject to dynamic myObject and it should be fine. I've no idea what you're trying to do with the last line though... Commented Nov 4, 2014 at 16:05
  • Normally would be duplicate of stackoverflow.com/questions/10338018/…, but now-days using dynamic is better option of this particular case. Commented Nov 4, 2014 at 16:19

2 Answers 2

2

In addition of dcastro answer's (which is good), I would like to suggest a third solution, which looks much cleaner to me : as "ReportingClassName" is your own code, you could modify it to make it realize an interface which provides what you need :

namespace MyCompany.MyApplication.ReportingClasses
{
public interface IReporting
{
    string HTMLReportString {get;}    
}

public class ReportingClassName : IReporting
{
    public string HTMLReportString {get; private set;}

    ReportingClassName()
    {
        // Use linq to generate report;
        // Populate gridview, pass object to function which returns HTMLString;
        // set HTMLReportString property;
    }

}
}


string myAssembly = "AssemblyName"; // This is static;
string myClass = "AssemblyQualifiedName"; // This value from DDL;
var myObject = Activator.CreateInstance(AssemblyName, AssemblyQualifiedName);

string propertyValue = ((IReporting)myObject).HTMLReportString; // Thanks to the interface, myObject provides HTMLReportString and it doesn't need reflection neither "dynamic".

"UpdatePanelID".InnerHTML = propertyValue;

For the last part, you could also do :

string propertyValue; 
var myReport = myObject as IReporting
if(myReport != null)   
{ 
    propertyValue = myReport.HTMLReportString; 
}
else 
{ 
    // Handle the error  
}

Just to be safer.

Sign up to request clarification or add additional context in comments.

7 Comments

+1, I forgot to mention this. If you can modify these classes, make them all implement a common interface.
Thanks dcastro, I did implement the the common interface on all objects. This also taught me quite a bit about the usefulness of Interfaces, so that is awesome. Richard, I marked this answer as correct, but there was one oversight, (IReporting)myObject should be (IReporting)myObject.Unwrap(). Once I added that method, it worked as advertised! I edited your response to reflect that change so the entire solution would be contained in the body of the response instead of in the comments. I appreciate all the help!
"Unwrap()" ? Where does this come ? Activator.CreateInstance returns an instance of the given type. Unwrap has no meaning in this case. I'm not sure to understand what you're talking about. But of the course the most important is that you got what you want.
When I implemented the solution you gave I received an error (Paraphrased) "Can not convert type ObjectHandler to type IReporting." I searched for the error and found this post link. Based on that post I implemented the Unwrap() method and it cast perfectly. I hope I didn't offend with my edit. Your answer really did solve my issue.
@UncleJasper75 is right - this specific overload of Activator.CreateInstance returns an ObjectHandle that needs to be unwrapped, not an Object. I must admit I was surprised myself, as most other overloads of this method, such as this one, return an object - which doesn't need unwrapping.
|
2

myObject is of type object, so obviously it doesn't have any property named HTMLReportString.

Since you don't know the type of myObject at compile time, you'll have to either:

  1. use reflection to invoke the property

    string value = (string) myObject.GetType()
                                    .GetProperty("HTMLReportString")
                                    .GetValue(myObject); 
    
  2. use dynamic typing

    dynamic myObject = //...
    string value = myObject.HTMLReportString;
    

2 Comments

Is there a difference in IL between these two cases?
@Dialecticus Yes, the second code will actually only be compiled at runtime by the DLR. I'm not sure which would have the best performance, you'd have to test this yourself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.