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.
Related
I feel like I should preface this by saying, I am still a beginner and knowing me, I could very well be forgetting something that is ridiculously simple and over complicating in the process. But nonetheless, I have been unable to figure this out.
I’m trying to create a dialogue system in unity that displays a string of text as well as a sprite. However, I am not sure how to pull the string from a separate class while also ensuring that I can keep the class in a list so I can cycle through the text and sprite together. Currently the class I'm attempting to pull from looks like this:
public class DialogueInfo
{
public Sprite emotion;
public string Words;
}
The list looks like this:
public List<DialogueInfo> dialogueInfo = new List<DialogueInfo>();
And I'm trying to use the "Words" string here:
NPC.dialogLines = dialogueInfo.Words;
This however, does not work. I am getting an error saying that "'List<dialogueHolder.DialogueInfo>' does not contain a definition for 'Words' and no accessible extension method..." Any suggestions? This whole process could be a very bad way of doing things and if so, suggestions would be appreciated. If more context is needed, I will gladly provide it.
Note: by using a list i am just trying to keep a format that looks like this: Unity's formatting of a list/array but with both text and a sprite in a single element If I have to use a different approach then that is alright.
Your variable name dialogInfo is misleading. It's not a dialogInfo, it's a box (a list) where there is a lot of dialogInfo inside.
Let's call it dialogInfoList instead.
public List<DialogueInfo> dialogueInfoList = new List<DialogueInfo>();
Extract all the words
If you want to get all the "Words" properties of all the element, you can use linq for this:
NPC.dialogLines = dialogueInfoList.Select(dialogInfo => dialogInfo.Words);
Depending on the type of NPC.dialogueLines (List for instance), you may want to add .ToList() after the Select().
Simpler: just link all the original list
You mentioned you might miss something simpler.
It really depends on what you want to achieve, the quesiton is not very clear about that, but what about keeping all the "DialogInfo" list with the NPC object instead?
Something like:
NPC.DialogueInfoList = dialogueInfoList;
With DialogueInfoList being a property / field of type List<DialogueInfo>
I am trying to dynamically add field properties to a record class that I am also building dynamically using FileHelpers.Dynamic.DelimitedClassBuilder. I have no issues creating the class object and I currently add a field using the AddField(String) method.
As my apps grows I now have a need to declare specific field properties in various situations. So in the same sense I wanted to use FileHelpers.Dynamic.DelimitedFieldBuilder to create a field object and then pass that to my DelimitedClassBuilder object using the method AddField(DelimitedFieldBuilder).
However I am unable to instantiate a new object using FileHelpers.Dynamic.DelimitedFieldBuilder. When I issue the following code I get an error stating that DelimitedFieldBuilder does not contain a constructor that takes two arguments.
FileHelpers.Dynamic.DelimitedFieldBuilder fb = new FileHelpers.Dynamic.DelimitedFieldBuilder("ClassName", "Type");
Looking at the documentation it appears that this class does only have properties associated with it, so I am kind of stuck on how to actually implement this. It seems like it should be fairly easy but I cant seem to figure it out. Thanks for any help.
Not familiar with that functionality of file helpers; however, in the vast majority of functions/methods across .NET there is usually a way to assign properties after the class is instantiated.
Try something like this:
FileHelpers.Dynamic.DelimitedFieldBuilder fb = new FileHelpers.Dynamic.DelimitedFieldBuilder();
fb.Whatever = "ClassName";
fb.otherwhatever = "Type";
Just a stab. I have no idea if it will work or not.
The constructors of DelimitedFieldBuilder are internal so you'll run into difficulty with your approach. However AddField(String) returns a DelimitedFieldBuilder, so you might be able to use that.
It might be easier to make your own class MyFieldBuilder which calls the standard AddField(String).
I am building web service in C# for a particular application, I have a XML definition of module. I have created a class called Field that holds the properties of all fields on a module. What I would like to do is create the field objects but name them dynamically then add them to a list of some sort. So when I reference them from the client it would be like this:
Module.Fields.MyDynamicName.FieldProperty
Is this possible to do? and could anyone point me in the right direction on how to do this.
Hope my question makes sense.
Basically you need to design for "deferred design", which means you do not know at compile time what the design is, but you still need to accommodate it.
There are probably a few ways but what I have done in the past is use a dictionary list of Key/Value pairs to store fields. Using serialization (I prefer Json) you can shove just about anything into a string and store it as the Value, then deserialize it when you need it.
Apologies if I've framed the question incorrectly but I'm not sure where it fits in exactly.
I am executing a powershell script from C# which returns a collection of type PSObject. The data I want is contained in the field BaseObject and when debugging it tells me its type is (PowerShellInside.NetCmdlets.Commands.MessageInfoObject) and I can see all the information there. So my question is assuming that a 3rd party vendor assembly is not available to be referenced, what is the correct approach to retrieving data from this object say
(PowerShellInside.NetCmdlets.Commands.MessageInfoObject).Subject
Do you create your own version of this class omitting what you dont need or is there some neat dynamic typing that can be done.
I'm not a POSH developer so I'll take this from the C# angle.
I'll assume PSObject is the equivalent of System.Object and MessageInfoObject is the type returned from the script... I'd say using something like the following should work:
dynamic msgInfo = ExecutePOSHScript(...);
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.