I'm referencing c# resource strings from my template (which uses $ as delimiters). I'm doing so by passing in as one of the arguments to the template the object "strings", which is a c# ResourceManager. The formatString is expected to be the name of the resource desired. This allows me to put in my template for example:
<Name>$strings;format="ItemName"$</Name>
The only issue with this solution is, there are times I want something from my object tree to help build the name of the resource string to look up. For example, a generic lookup for a localized value for an enum could be provided with:
<Type>$strings;format="ItemType$myItem.Type$"$</Type>
However - when I attempt to call the renderer this way, if I use the above syntax, the myItem.Type is not resolved into its value, and instead passed directly as part of the string, so I get the value "ItemType$myItem.Type$" rather than say, "ItemTypeBicycle".
If I don't place quotes around it however, such as:
<Type>$strings;format=ItemType$myItem.Type$$</Type>
I get a compile-time error that this "doesn't look like an expresson"
Is there another syntax I'm missing, or are you not able to resolve something that is then passed as a string like this?
Related
So, I'm using the XML Type Provider to create types from an XML document.
One of the elements in the XML file has a Date property:
<Edit Date="06/30/2015 16:57:46"
... />
Which of course results in a Type like this:
type Edit =
inherit XmlElement
member Date: DateTime
...
Is there a way that I can add the following code:
member this.LocalTime
with get() =
this.Date.ToLocalTime()
To the resulting Edit type?
The reason for this is that I'm binding to instances of Edit from XAML and I really don't want to write an IValueConverter just to do that.
Edit:
So, I just realized that these types do not make it to my XAML. Instead, I get instances of FSharp.Data.Runtime.BaseTypes.XmlElement which of course do not even contain the properties I see in F# code. I also need to consume these types from C# code, and even there I get only XmlElements without the properties
I know I could use XPath in XAML to navigate the XElements inside this, but I still need a way to access the resulting object model in a strongly typed way, both from C# and XAML.
Edit2:
So now I wrote a Type Extension like this:
type Catalog.Edit with
member this.LocalTime with get() = this.Date.ToLocalTime()
And I see the member in F# code just like the generated members. However there's 2 drawbacks to this approach:
1 - It forced me to change my namespace into a module, which is less convenient since these types are all consumed from C# code and in there I see them as nested classes into the module class, which is ugly.
2 - I still can't see this member (nor the generated ones) from either C# nor XAML.
What's the correct way to implement this in the described scenario?
The F# Data type providers for XML and JSON are erasing type providers. This means that the types you see when you use them from F# do not actually exist at runtime - they are replaced with some underlying runtime representation (here XmlElement).
Unfortunately, this means that the types are not real types and so they are only visible to F#.
My recommendation is to define a simple domain type using F# records and load your data from the XML into your records. This is a bit more work, but it also gives you a bit more safety, because you are explicitly defining the structure - and so if your XML changes, you'll know you need to change your XAML code too!
It should be as easy as something like this:
type Edit = { Date : DateTime }
let GetData () =
let doc = MyXmlType.Load("somefile.xml")
seq { for item in doc.Edits -> { Date = item.Date } }
I am writing a customer class which will read CS files and spit out information based on method names and their various parameters.
This essentially reads each line looking for keys (public, class, etc) and then sees what its all about. Anyway this bit works fine, what I'm having issues with is dealing with various different Types.
So what I need to do is work out whether the type is one found natively in .Net, or something I've created, I'm really not bothered which way round just as long as I have some way of telling.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this just returns null even with the full namespace and name of my custom class object. However if I was to do the same code but with System.String it works perfectly fine, but I can't really account for each possible namespace in the entire framework. This will mean I need a way to get the type without the full namespace, or know how to check my own custom objects using GetType.
Can anybody provide any suggestions on how to go about this? Even if it was creating a new instance of the objects that would be enough, but again I don't have the full namespace for .Net objects.
Edit: Bit of a background
What I'm doing is reading classes that I've created in a StreamReader, reason being that I'm creating lots of them and need to do making between objects that one system will be able to understand, and another, so this code would read everything and just create the mapping for me. And in most cases this is perfectly fine, it is only when I have custom types, so I want to identify these are mark them.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this
just returns null
You need to provide the full assembly-qualified name:
Type t = Type.GetType("My.Namespace.Classname, MyAssembly");
From MSDN:
Parameters
typeName
Type: System.String
The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing
assembly or in Mscorlib.dll, it is sufficient to supply the type name
qualified by its namespace.
Anyway, if you're looking to parse C# code an analyze it, I would take a look at NRefactory - an open source C# parser -.
Here's an introduction in CodeProject to NRefactory.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this just returns null even with the full namespace and name of my custom class object.
I suspect that's because it's not in the calling assembly or mscorlib, which are the only two assemblies checked by Type.GetType for names which aren't assembly-qualified.
If you know all the assemblies involved, you could run through each of them calling Assembly.GetType(namespaceQualifiedName) on each of them.
However, if you don't even have the namespace-qualified name, you should possibly create a lookup of all types in all the relevant assemblies, based on their names. For example:
var lookup = assemblies.SelectMany(a => a.GetTypes())
.ToLookup(t => t.Name);
At that point, for each name you have(e.g. Classname in your example) you can find all the types with that name:
foreach (var type in lookup[name])
{
// Do something with type
}
Type.GetType(some_type_name) will return type object if some_type_name is name of type declared any assemblies loaded at the moment, or in Mscorlib.dll
So if your are parsing your types from .cs files and not loading assebly - it will always be null with types names from your source file
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(...);
I'm not really sure what tags should be on this sort of question so feel free to give me some suggestions if you think some others are more suited.
I have a dynamic object with an unknown number or properties on it, it's from a sort of dynamic self describing data model that lets the user build the data model at runtime. However because all of the fields holding relevant information to the user are in dynamic properties, it's difficult to determine what should be the human readable identifier, so it's left up to the administrator. (Don't think it matters but this is an ASP.NET MVC3 Application). To help during debugging I had started decorating some classes with DebuggerDisplayAttribute to make it easier to debug. This allow me to do things like
[DebuggerDisplay(#"\{Description = {Description}}")]
public class Group
to get a better picture of what a specific instance of an object is. And this sort of setup would be perfect but I can't seem to find the implementation of this flexibility. This is especially useful on my dynamic objects because the string value of the DebuggerDisplayAttribute is resolved by the .NET framework and I have implementations of TryGetMember on my base object class to handle the dynamic aspect. But this only makes it easier for development. So I've added a field on what part of my object is still strongly typed and called it Title, and I'd like to let the administer set the implementation using their own format, so to speak. So for example they might build out a very simplistic rental tracking system to show rentals and they might specify a format string along the lines of
"{MovieTitle} (Due: {DueDate})"
I would like that when they save the record to add some logic to first update the Title property by resolving the format string to substitute each place holder with the value of the appropriate property on the dynamic object. So this might resolve to a title of
"Inception (Due: May 21, 2011)", or a more realistic scenario of a format string of
"{LastName}, {FirstName}"
I don't want the user to have to update the title of a record when they change the first name field or the last name field. I fully realize this will likely use reflection but I'm hoping some one out there can give me some pointers or even a working example to handle complex format strings that could be a mix if literal text and placeholders.
I've not had much luck looking for an implementation on the net that will do what I want since I'm not really sure what keywords would give me the most relevant search results?
You need two things:
1) A syntax for formatting strings
You have already described a syntax where variables are surrounded by bracers, and if you want to use that you need to build a parser that can parse that. Perhaps you also want to add ways to specify say a date or a number format.
2) Rules for resolving variables
If there is a single context object you can use reflection and match variable names to properties but if your object model is more complex you can add conventions for searching say a hierarchy of objects.
If you are planning to base your model objects on dynamic chances are that you will find the Clay library on CodePlex interesting.
I've seen many questions and answers about mapping strings to enums and vice-versa, but how can I map a series of localized strings to enums?
Should I just create an extension method like this that returns the proper string from a resource file? Is there a way to localize attributes (like "Description") that are used in solutions like this?
Which is the preferred solution - extension method or attributes. It seems to me that this isn't the intended purpose of attributes. In fact, now that I think about it, if I were to use an extension method an attribute seems like something I'd use to specify a key in a resource file for the localized string I want to use in place of the enum value.
EDIT - example:
Given the following enum,
public enum TransactionTypes {
Cheque = 1,
BankTransfer = 2,
CreditCard = 3
}
I would like a way to map each type to a localized string. I started off with an extension method for the enum that uses a switch statement and strongly typed references to the resource file.
However, an extension method for every enum doesn't seem like a great solution. I've started following this to create a custom attribute for each enumerated value. The attribute has a base name and key for the resource file containing localized strings. In the above enum, for example, I have this:
...
[EnumResourceAttribute("FinancialTransaction", "Cheque")]
Cheque = 1,
...
Where "FinanacialTransaction" is the resx file and "Cheque" is the string key. I'm trying to create a utility method to which I could pass any value from any enumeration and have it return the localized string representation of that value, assuming the custom attribute is specified. I just can't figure out how to dynamically access a resource file and a key within it.
I would definitely suggest using a resource file, probably with a method (extension or otherwise) to make it simple to get hold of the relevant resource. As the number of languages you support grows, you don't really want the code to be full of text, distracting you from the values themselves.
Likewise translation companies are likely to be geared up to handle resx files - they're not going to want to mess around in your source code, and you shouldn't let them do so anyway :)
Just use resources which are keyed on the name of the enum and the value within it. Straightforward, scales to multiple enums and multiple languages, doesn't clutter up your source code, works well with translation tools, and is basically going along with the flow of i18n within .NET.
EDIT: For mapping the enum values to the resource names, I'd just do something like:
public static string ToResourceName<T>(this T value) where T : struct
{
return typeof(T).Name + "." + value;
}
Then you could do:
string resource = MyEnum.SomeValue.ToResourceName();
Obviously that's performing string concatenation every time - you could cache that if you wanted to, but I wouldn't bother unless you had some indication that it was actually a problem.
That doesn't stop you using the extension method for non-enums, of course. If you want to do that, you need something like Unconstrained Melody.
I continued with the custom attributes and created this utility method:
public static string getEnumResourceString(Enum value)
{
System.Reflection.FieldInfo fi = value.GetType().GetField(value.ToString());
EnumResourceAttribute attr = (EnumResourceAttribute)System.Attribute.GetCustomAttribute(fi, typeof(EnumResourceAttribute));
return (string)HttpContext.GetGlobalResourceObject(attr.BaseName, attr.Key);
}