i have a problem, the functionality I'm looking for exactly is:
I have a grid and datagrid, according to the line to select the datagrid there will be to introduce a user control or other user controls are different pictures I've made polylinesegments, bezier cuadratic ... to introduce the call will name, which build on a string, but I have no way to call it correctly.
This is what I do and it works by putting the full name:
d48.Children.Add(new tratsPintados.end148());
But put the string, tells me not find the path in the project, what I want is to find the path inside the string.
d48.Children.Add(new thestring());
Any ideas?
If you need to instantiate some class based on its name (without real reference), you will need to use Reflection.
Maybe you can do some lookup by name for the class you need, and then use Activator.CreateInstance to call its default constructor.
I hope this is what you want, the question text is quite confusing to me.
using System.Reflection;
public object GetObjectFromString()
{
string objectName = "WpfApplication1.uc1";
Type newType = Type.GetType(objectName, true, true);
object o = Activator.CreateInstance(newType);
// do what you want with the 'o' variable, maybe cast it to the type you want.
}
Related
I need dynamic rendering email template from the specific object from my domain model. I know I can create objects and inherit it from Drop class. Also, I know I can add the specific type to safe type globally, but this doesn't solve the problem.
How to render a template from my specific types?
var message = _template.Render(Hash.FromAnonymousObject(new {Item = User}));
public class User { public string Name { get; set;}.....}
Safe type doesn't suitable for this task because in my specific object has nested objects and I need an access to them too.
Template.RegisterSafeType(typeof(User,string[] allowedMembers));
I can inherit my specific types from Drop class of dotliquid assembly but I think it doesn't help me.
RegisterSafeType is the solution if you want to avoid Drop and the alternatives.
Simply register all the relevant types (approximate code):
Template.RegisterSafeType(typeof(User), userAllowedMembers);
Then say User has a property of type Address. You can simply continue the registration with
Template.RegisterSafeType(typeof(Address), addressAllowedMembers);
Dim TemplateContent = CacheHelper.GetFileContentsNonCached("/Path/To/Template/File.htm")
Dim TemplateParsed = DotLiquid.Template.Parse(TemplateContent)
Return TemplateParsed.Render(Hash.FromAnonymousObject(New With {
.Item = User,
......
}))
Above code is in VB.Net but easy to convert to C#.
This doesn't require to register any type safe etc.
I have a bit of a weird issue. Working in C# script with SSIS I have developed a need to build a List based off Dynamic Data.
Background
To explain it, a script task is fired that has a variable API URL, this goes off and pulls a JSON string back and then throws it into a strongly typed list using the following code.
var listobject = get_APIData<ApplicationOneDataSet>(url)
The class that does this is long winded and not really needed in the context of this issue.
ApplicationOneDataSet is a strongly typed match to one of the possible JSON results returned by get_APIData.
Now I have a need to change ApplicationOneDataSet to ApplicationTwoDataSet dynamically based on which API URL I pass to the script.
So what I have done is send through a second variable to the script called class name which contains the string "ApplicationDataSetOne" or "ApplicationDataSetTwo" based on which context I call it under.
The Question
My question is how can I dynamically vary this line:
var listobject = get_APIData<ApplicationOneDataSet>(url)
With the string variable passed into the script.
My original thinking was something along the lines of this:
var ClassType = (string) Dts.Variables["AppClassName"].Value;
Type type = Type.GetType(ClassType);
var listobject = get_APIData<type>(url)
Though it doesn't seem to like that. Any tips would be great!
As long as there is exactly two types you can use and you know them at compile time, I would not look further than a simple if. It works, it's easy, everyone understands it.
You can do it totally dynamic at runtime, but that's a huge pain in the... where you don't want it to be. If you really want to go down that rabbit hole, you can find more information here.
I'm not sure I fully understood what you are trying to do, but how about writing an interface ApplicationDataSet and then making a list of it? This way your list is going to be able to contain both types of data.
SHORT VERSION
What's the best way to use reflection to turn something like string prop = "part1.first_name"; into a System.Reflection.PropertyInfo, so that I can use the GetValue and SetValue functions?
LONG VERSION
I'm using ASP .NET MVC to build a questionnaire for my organization. It's very long, so it's divided into several different pages. Since it's not uncommon for us to get requests like, "Can you move this question to that page, and this other question to another page," I need to build this to be pretty flexible for a junior programmer to change.
My model is a complex class (it's got five member classes that have mostly primitive-typed properties on them).
So, I access it by doing things like Model.part1.first_name or Model.part2.birth_date.
Since the same model is used on all of the pages, but not all of the questions are on every page, I have ActionAttributes that essentially clear out all of the properties that were submitted on the form except for the ones that were displayed on that page (so someone can't inject a hidden field into the form and have the value persist to the database).
I want to make sure that I only save valid field values and don't let the user proceed to the next page until the current one is entirely OK, but I also want to save the values that are valid, even if the user isn't allowed to proceed.
To do this, I have a function that takes two instances of my model class, a reference to the ModelStateDictionary, and a string[] of field names like "part1.first_name" and "part2.birth_date". That function needs to copy all of the values listed in the string array that do not have validation errors from the first (ie, form-submitted) object into the second (ie, loaded from the db) object.
As stated above, what's the best way to use reflection to turn something like "part1.first_name" into a System.Reflection.PropertyInfo, OR, is there a better way to accomplish this?
var infoParts = prop.Split('.');
var myType = Type.GetType(infoParts[0]);
var myPropertyInfo = myType.GetProperty(infoParts[1]);
Assuming "part1" is your type. Although this is very limited and very dependent on the string being in the correct format and the type being in the current scope.
I would probably handle this differently, using data. I would keep, in the database, which step each question belongs to. To render that step, I would select the questions that match that step and have a model that contains a list of question id/question pairs. Each input would be identified by the question id when posted back. To validate, simply compare the set of question ids with the expected ids for that step. This way, to change which question goes in which step is to only change the data in the database.
If you do end up going down that road, you'll need to split the string into parts and recursively or iteratively find the property on the object at each step.
PropertyInfo property = null;
Type type = questionModel.GetType();
object value = questionModel;
object previousObj = null;
foreach (var part in questionId.Split('.'))
{
property = type.GetProperty(part);
previousObj = value;
value = property.GetValue(value,null);
type = value.GetType();
}
// here, if all goes well, property should contain the correct PropertyInfo and
// value should contain that property's value...and previousObj should contain
// the object that the property references, without which it won't do you much good.
Ok, I've thumped on this idea all day now, and I have reached the part where I admit I just flat out don't know. It's possible that what I'm doing is just stupid and there is a better way, but this is where my thinking has brought me.
I am attempting to use a generic method to load forms in WinForms:
protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
// Do some stuff
}
The forms are loaded by a ToolStripMenuItem (either through the selection of the item or using the Open Windows menu item). They are lazy-loaded, so there are fields for the forms within the MDI parent, but they are null until they are needed. I have a common method used for ToolStripMenuItem_Click that handles all of the menu item clicks. The method has no real way of knowing which form is being called for except that the name of the ToolStripMenuItem matches a pattern chosen for the form class names they correspond to. So, using the name of the ToolStripMenuItem, I can divine the name of the type of form being requested and the name of the private field allocated to store the reference for that form.
Using that, I can either use a growing/contracting switch statement with hard-coded types and string matches to call method with the specific type set (undesirable), or I can use Reflection to get the field and create the instance of the type. The problem to me is, System.Activator.CreateInstance provides an ObjectHandler that can't be cast to the types that I need. Here is a snippet of what I have so far:
string formName = "_form" + ((ToolStripMenuItem)sender).Name.Replace("ToolStripMenuItem", "");
string formType = formName.Substring(1);
FieldInfo fi = this.GetType().GetField(formName, BindingFlags.NonPublic | BindingFlags.Instance);
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
formToLoad = (????)System.Activator.CreateInstance("MyAssemblyName", formType);
}
this.LoadForm(ref formToLoad, false);
fi.SetValue(this, formToLoad);
I know the string name of the type that goes in for (????) but at compile-time I do not know the type because it changes. I have tried a bunch of ways to get this cast/instantiation to work, but none have been successful. I would very much like to know if it's possible to perform such a cast knowing the type only as a string. I tried using Type.GetType(string, string) to perform the cast, but the compiler didn't like it. If someone has a different idea on how to load the forms dynamically because I'm just doing it stupidly, please let me know about it.
This problem is usually resolved by casting to a common base class or interface of all potential types.
In C# 4, you can also assign it to a dynamic variable to hold the return value and call arbitrary methods on it. The methods will be late bound. However, I prefer to stick to the former solution whenever possible.
You'd be better off with the other overload that takes a Type and using e.g. Type.GetType(string).
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
formToLoad =
(FormWithWorker)System.Activator.CreateInstance(Type.GetType("MyNamespace.MyFormType"));
}
According to what you have, FormWithWorker must be (at least) as base class of the type you are instantiating, so you can do this:
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
formToLoad = (FormWithWorker)System.Activator.CreateInstance("MyAssemblyName", formType);
}
While a common interface is one way to approach this problem, interfaces aren't practical for all scenerioes. The decision above is one of going with a factory pattern (switch statement - concrete class selection) or use reflection. There's a stack post that tackles this problem. I believe you can directly apply this to your issue:
Method Factory - case vs. reflection
I'm trying to add Intellisense to C# code editor based on the richtextbox control. So far, I've got it parsing the entered text to find all variables and their types (works well). The drop down box works well. What I can't get is a proper list of options for the drop-down list box.
How can I get the following list, programmatically:
I have already compiled a list of variables and their types, so when the user presses . I know that I have a variable c of type Color. I just need to know what function to call to get the list I need for the drop-down box.
I've tried this code: http://www.codeproject.com/KB/cs/diy-intellisense.aspx but couldn't get it to work properly. I've also read a ton of other threads on StackOverflow to no avail. I'd really like to finish this instead of using someone elses drop-in editor component.
Any hints would be appreciated. Thanks.
If you know the type, you should be able to Reflect on the type and get all the information you need.
Type.GetMembers would probably be your best bet. You may need a second call to get any static methods as well:
var instanceMembers = typeof(Color)
.GetMembers(BindingFlags.Instance | BindingFlags.Public);
var staticMembers = typeof(Color)
.GetMembers(BindingFlags.Static | BindingFlags.Public);
Each MemberInfo object will be able to tell you the MemberType (Property, Field, Method, Event, etc.)
Just use the instanceMembers when the user types a variable (like c in your example) followed by . and use the staticMembers when the user types a type name (like Color in your example) followed by ..
Assuming you have a name table with types this should give you a decent start:
var type = _names[name].Type;
var members = type.GetMembers(); // Check context to grab private methods?
So maybe you can extend your name table to include:
Type
Context
Members
You'd want to use reflection to some degree. If you have the type, or the name of the type, you can get a Type instance.
E.g. Type.GetType("System.Int32")
Then you can call Type.GetMembers() on that Type object, see here:
http://msdn.microsoft.com/en-us/library/424c79hc.aspx
...and you'll have an array of MemberInfo objects which have the name (.Name), type of the member (.MemberType), and from that other information, like parameter lists.
Hope that helps.