FileHelpers - Creating a field object - c#

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).

Related

C# Dynamic List Class

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.

Microsoft.Management.Infrastructure Namespace - Cim classes

I'm using new new Microsoft.Management.Infrastructure classes to handle WMI, but I've encountered a stumbling block, and can't find any information on how to work around this using these classes without having to fall back to using System.Management.ManagementObject.
Basically, Microsoft.Management.Infrastructure doesn't expose any methods for objects, which is what I'm having difficulties with.
I've retrieved a CimClass object, let's call it Win32_Process , called the property .CimClassProperties["Handle"] to get the Handle property and .Qualifiers to retrieve a list of qualifiers for the Handle property.
At this stage I'd like to delete one of the qualifiers, but there are no methods exposed that allow such a thing.
Using Microsoft.Management.ManagementObject namespace, I could get a ManagementClass object, again Win32_Process for the sake of the argument, call .Properties["Handle"].Qualifiers.Remove(<qualifierName>) to remove the qualifier, but no idea how to do this using the new classes and there's no info out there that I can find.
EDIT: I did some digging and found that to invoke methods on CIM objects you use the CimSession class, using either CimSession.InvokeMethod or CimSession.InvokeMethodAsync methods and was able to use it to invoke a method of a CimClass and of a CimInstance, but it does not appear to be able to invoke methods of any object outside of those two, from what I can see. Is this me?
I believe, it is not possible to modify the Qualifiers. Reason is it is read only property. Also, if you want something to do in code, they take the data in list or string array and manipulate them.
This is a very late answer, but I have found myself in a similar situation with trying to change Win32_TCPIPPrinterPort Printer IP Addresses and Names, which are also ReadOnly. I did come across some articles that refer to wbemtest.exe. This utility can be used to make changes like this, but use extreme caution as it is a WMI-Object editor and can break your system. This link will explain it better https://blogs.technet.microsoft.com/heyscriptingguy/2009/08/04/hey-scripting-guy-how-do-i-use-wmi-with-windows-powershell-to-return-information-about-properties/

Get all writeable properties of an ADLDS-Class

I'm developing an application which can deal with a MS-ADLDS-Service.
Currently it is possible to create Directory-Entries and assign values to some properties.
Not a realy exciting task until this:
Im my application it's possible (it should be) to configure which properties of a class (for instance: the CN=Person class) should be assigned with values which are evaluated at runtime in my application.
Long story short:
I want to retrieve all (writeable) properties of a class. Without creating and saving a new CN=Person-Object before.
Currently i use my schemaBinding to get the Directory-classSchema-Entry of the Person-Class (CN=Person) from where i read some property-values (like "AllowedAttributesEffective", "mayContain", "AllowedAttributes") - i get the most properties by this way - but some Properties are missing! For instance the "telephoneNumber"-Property (attributeSchema: CN=Telephone-Number)
Does anybody know how to get these properties of a class? ADSI-Edit does this: when i create a new object with adsi-edit i can assign values to all possible properties before committing the new entry.
thanks a lot for any hint!
(.net code is welcome)
I have found the solution for my task!
Some of these properties are "calculated" and not persistent at the directoryentry.
So its meant to call the RefreshCache() Method and pass the needed property names as an string array.
directoryEntry.RefreshCache(new string[] { "allowedAttributesEffective",
"allowedAttributes",
"systemMayContain",
"systemMustContain" });
After that call, the properties have values....
if (directoryEntry.Properties["systemMayContain"]).Value != null)
{
/// Success
}

Apple's Key Value Coding - can somebody explain to a C# developer why I would need this and what it does?

Before I switched to iOS development via Monotouch I played around a bit with ObjectiveC. Ever since one thing has been on my mind "Key Value Coding" (KVC). I have never understood what it is good for and what the magic behind it is.
For my understanding it is just a collections of names and values, like .NET's NameValueCollection: Instead of setting anObject.Address = "An address Value" you would write anObject.Properties["Address"] = "An address value".
Great. So what? Because this appears to be too easy to me I'm sure that can't be it.
Or is it because .NET has reflection and therefore has no need for something like Key-Value-Coding? I can grab the type of "anObject" and use reflection to loop all of its properties and look for the one called "Address" and then use reflection to set the value.
Is that maybe the analogy of KVC?
I'm hoping there is somebody out there who's a pro in ObjC and C#/.NET who can explain to me what the benefits are and how it would translate into .NET.
Please don't just point me to Apple's documentation. I know all that. I'm trying to find out if something has been missing in my coding-life so far by not knowing KVC? Or have I maybe been using something similar in .NET not being aware that it would translate into KVC if I was using ObjC?
From somebody who uses both every day for probably 3 years now:
As you figured out, there's nothing amazingly complex in KVC that can't be done with dictionaries and NameValueCollections in C#.
The big difference is that KVC is built in the language. An object in Obj-C IS a NameValueCollection. You don't have to change the way you develop (from classes and properties to dictionaries) to use it. You can create your object with the properties you want, and then later on call a valueForKey:#"name", and everything still works.
Now you can say: "yeah cool, but I can do that with reflection!". Sure you can, but just as before, you'll have to change the way you develop again, not counting the fact that reflection is a lot slower in general.
Another cool feature of KVC it it allows you to use KVO, which basically allows you to register to receive notifications about changes in any object without having to write a single line of code in those objects. So, in any object in your application, you can call "addObserver:forKeyPath:", and receive a callback if anybody else in your application changes that property. This is really useful for live apps, like iOS apps.
Again, you can implement KVO in C# (MVVM frameworks for example do this all the time), but you have to write extra code for that. In Obj-C, it's built in the language.
I blogged about this in the context of MonoMac, the peer project to MonoTouch but used for building Mac applications:
http://tirania.org/monomac/archive/2010/Dec-07.html
Key-Value Coding is a set of practices that allow applications to access object properties using strings. This is similar to Binding Expressions in Silverlight. In both cases the purpose is to allow tooling that does not directly have access to your native code to access properties from your program.
In particular, this is useful because some APIs can take advantage of this. For example CoreAnimation can animate properties given their "path" to the object. For example, you can do:
var animateX = CAKeyFrameAnimation.FromKeyPath ("position.x");
pos.Values = new NSNumber [] { 0, 10, 60 };
layer.AddAnimation (animateX, "move");
The "position.x" in this case references the layer's position, and within that position it's X component.
The blog post above goes into more detail about how you can actually expose your own objects to participate in this protocol (registering your own properties to make them visible to the Key-Value-Coding system).
Kenneth, another one of the MonoMac developers blogged about this extensively here:
http://cocoa-mono.org/archives/153/kvc-kvo-and-cocoa-bindings-oh-my-part-1/
In particular he deals with the similarities with Reflection and he shows you how to use [Export] to turn your C# code into KVC compliant code as well.
If you access a property like this
anObject.Address = "An address Value"
The code will be very "static". It will always access Address
You can create a more dynamic code like this
void SetProperty (string propertyName, string value)
{
anObject.Properties[propertyName] = value;
}
You would do this if you do not know at compile time which property will be accessed.
In c# you would typically use a Dictionary<TKey,TValue> for storing key/value pairs. Automatically accessing properties via KVC as in Objective-C is not supported in c#. You would either declare the property as
public Dictionary<string,string> Properties { get; private set; }
and instantiate it in the class constructor with
Properties = new Dictionary<string,string>();
then you could access it like this
anObject.Properties[propertyName] = value;
Or you would have to use Reflection to access the property
Type type = anObject.GetType();
// Or Type type = typeof(TypeOfAnObject);
PropertyInfo prop = type.GetProperty(propertyName);
prop.SetValue(anObject, propertyValue, null);
However, this is not very efficient.

Fastest way to use reflection for converting datareader to list

I am using reflection to convert datareader into the generic collection list. Can anybody
suggest me the best way to implement reflection for this? I want the fastestway?
I assume what you want to do is something like:
List<MyClass> list = LoadFromDataReader<MyClass>(dataReader);
with:
class MyClass
{
[DataField("FirstName")] public string FirstName { get; set; }
[DataField("LastName")] public string LastName { get; set; }
}
I do this by:
Using Type.GetProperties and PropertyInfo.GetCustomAttribute to put together a dictionary mapping field names to PropertyInfo objects
Calling PropertyInfo.SetValue on each field in each record
You can cache the results of step (1), since the field/property mapping isn't going to change during the life of the application.
If performance is a problem (i.e. if step (2) turns out to be a bottleneck), then you have to avoid using reflection and generate code to set the properties directly. A couple of alternative improvements:
Use System.CodeDom to generate a C# class containing code to set the properties according to the respective fields on the IDataReader. Note that System.CodeDom invokes the csc.exe compiler in the background, so you need to generate this code once at startup and re-use it on each call.
Use System.Reflection.Emit.DynamicMethod to generate IL code that sets properties. Less runtime overhead than System.CodeDom, but since you're generating raw IL, this is much harder to write and debug. Use as a last option.
This really depends on exactly what you are looking at doing. I implement a object/interface process where I create information objects that hold the data that is returned. I then use an interface IFillable or something similar that passes a DR to the object and the object does the hydration from the DR.
This way I avoid the need for reflection, and the performance is great. I then have a few generic helper methods for Fill and FillCollection.
I got the idea based on stuff inside the CBO object of the DotNetNuke framework. It also implements a reflection method as well, that is fairly decent in performance.

Categories