How to retrieve static property of DLinq entity

A

Andrus

I need to associate text used in messages with every DLinq entity type.
I need to retrive this text from entity name.

I tried to solve this by creating public static readonly property Text in
every entity and
use EntityManager.GetText() method.

Is this best way or is there any better idea ?
The code below causes compile time erorr shown in comment. How to fix this ?

Andrus.

using System;
using System.Reflection;

class Test {
static void Main() {
// must output: This is customer type
Console.WriteLine(EntityManager.GetText("CustomerBaseClass"));

// must output: This is some supplier entity
Console.WriteLine(EntityManager.GetText("SomeSupplierClass"));

}
}


static class EntityManager {
public static string GetText(string name) {
// error: Cannot convert type 'System.Reflection.PropertyInfo' to
'string' via a reference conversion, boxing
// conversion, unboxing conversion, wrapping conversion, or null type
conversion
return
(Assembly.GetExecutingAssembly().GetType(name).GetProperty("Text")) as
string ;
}
}


class EntityBase { }

class CustomerBaseClass : EntityBase {
public static readonly string Text = "This is customer type";
}

class SomeSupplierClass : EntityBase {
public static readonly string Text = "This is some supplier entity";
}
 
J

Jon Skeet [C# MVP]

Andrus said:
I need to associate text used in messages with every DLinq entity type.
I need to retrive this text from entity name.

I tried to solve this by creating public static readonly property Text in
every entity and
use EntityManager.GetText() method.

Is this best way or is there any better idea ?

I don't know, to be honest.
The code below causes compile time erorr shown in comment. How to fix this ?

static class EntityManager {
public static string GetText(string name) {
// error: Cannot convert type 'System.Reflection.PropertyInfo' to
'string' via a reference conversion, boxing
// conversion, unboxing conversion, wrapping conversion, or null type
conversion
return
(Assembly.GetExecutingAssembly().GetType(name).GetProperty("Text")) as
string ;
}
}

Well, look at what the compiler is telling you - GetProperty() returns
a PropertyInfo. How are you going to try to convert that into a string?
If you want to find the value, you'll need to specify an object to
retrieve it from.
 
A

Andrus

Jon,
Well, look at what the compiler is telling you - GetProperty() returns
a PropertyInfo. How are you going to try to convert that into a string?
If you want to find the value, you'll need to specify an object to
retrieve it from.

thank you.
I don't have object created.
I want to to retrieve static const field from type:

class MyEntity {
public static const string Text="My Entity description";
}

if this is not possible /reasonable, I can try other solutions:

1. Use readonly field :

public static readonly string Text="My Entity description";

2. Use Property:

public static string Text { get { return "My Entity description"; }}

3. Use static method:

public static string Text() { return "My Entity description"; }

4. Use Atrribute

[Description("My Entity description")]
class MyEntity { }

5. Use separate xml file or entity descriptor class

Which is the best way to create GetText(entityTypeName) method to define and
retrieve text from entity type ?
I don't have entity object created. Should I create dummy object only for
Text retrieve or is it possible to retrieve text from type directly ?

Andrus.
 
M

Marc Gravell

There's no such thing as "static const"; but you can get both a static
property and a const as below.

But I would *absolutely* use the attribute approach myself. It is far
tidier; I'm a big fan of metadata for this type of thing... In
particular, the property/const approaches don't work very well with
inheritance, where-as attributes work just fine...

Marc

using System;
using System.Reflection;
using System.ComponentModel;

[Description("My Entity description")]
class MyEntity
{
public const string ConstText = "My Entity description";
public static string PropText { get { return "My Entity
description"; } }
}
static class Program
{
static string GetDescription(Type type)
{
foreach (DescriptionAttribute attrib in
type.GetCustomAttributes(typeof(DescriptionAttribute),
true))
{
return attrib.Description;
}
return null;
}
static void Main()
{
Type type = typeof(MyEntity);
string foo = (string)type.GetProperty("PropText",
BindingFlags.Static | BindingFlags.Public).GetValue(null, null);
string bar = (string)type.GetField("ConstText",
BindingFlags.Static | BindingFlags.Public).GetValue(null);
string tidier = GetDescription(type);

}
}
 
J

Jon Skeet [C# MVP]

Andrus said:
thank you.
I don't have object created.
I want to to retrieve static const field from type:

class MyEntity {
public static const string Text="My Entity description";
}

if this is not possible /reasonable, I can try other solutions:

It would be possible (although you'd need to specify BindingFlags in
the call to GetProperty, I suspect, to say that you want a static
property - then call GetValue with "null" as the target).

However, I far prefer:
4. Use Atrribute

[Description("My Entity description")]
class MyEntity { }

Probably come up with your own attribute specifically for this purpose,
to keep things clear. You can use Type.GetCustomAttributes to retrieve
the value.
 
M

Marc Gravell

If you meant "static readonly" (instead of "static const") then the
code to read this is the same as for the const example - but I would
use a public static property (get only) in preference to a public
static field, and an attribute in preference to either.
 
A

Andrus

Marc,
[Description("My Entity description")]
class MyEntity
{
public const string ConstText = "My Entity description";
public static string PropText { get { return "My Entity
description"; } }
}
static class Program
{
static string GetDescription(Type type)
{
foreach (DescriptionAttribute attrib in
type.GetCustomAttributes(typeof(DescriptionAttribute),
true))
{
return attrib.Description;
}
return null;
}

Thank you. I need to display descriptions in different languages. I tried
use method call in Description() parameter but got compile error.

How to enable GetDescription() to return localized description corresponding
to current culture ?

Andrus.
 
J

Jon Skeet [C# MVP]

Andrus said:
[Description("My Entity description")]
class MyEntity
{
public const string ConstText = "My Entity description";
public static string PropText { get { return "My Entity
description"; } }
}
static class Program
{
static string GetDescription(Type type)
{
foreach (DescriptionAttribute attrib in
type.GetCustomAttributes(typeof(DescriptionAttribute),
true))
{
return attrib.Description;
}
return null;
}

Thank you. I need to display descriptions in different languages. I tried
use method call in Description() parameter but got compile error.

How to enable GetDescription() to return localized description corresponding
to current culture ?

Make the Description actually a key into a resource file, then use
resources as normal.
 
A

Andrus

Jon,
Make the Description actually a key into a resource file, then use
resources as normal.

Thank you.
How to create key "My Entity description" for resource file.
As I understand, resource file can be accessed only by resource id which is
identifier.

How to convert any description string to valid resource identifier ?

Andrus.
 
J

Jon Skeet [C# MVP]

Andrus said:
Thank you.
How to create key "My Entity description" for resource file.
As I understand, resource file can be accessed only by resource id which is
identifier.

How to convert any description string to valid resource identifier ?

Don't store a description string in there to start with - store a
resource ID.
 
J

Jon Skeet [C# MVP]

Don't store a description string in there to start with - store a
resource ID.

As an alternative, by the way - use a naming convention which allows
you to go straight from the type name to a resource ID; then you don't
need an attribute at all.
 
A

Andrus

Don't store a description string in there to start with - store a
resource ID.

Using resource ids insted of strings makes code unreadable since they tends
to be cryptic.

Do you have any idea how create method which converts string to valid C#
name (resource unique id).

E.q string like "Hello, world!" should be converted something like

Hello_44_32world_33

Andrus.
 
A

Andrus

As an alternative, by the way - use a naming convention which allows
you to go straight from the type name to a resource ID; then you don't
need an attribute at all.

This would be interesting idea.
Should I use reflection to retrieve string value ?

I'd prefer to convert any string to resource id, eq.

in every place use method

string I( string stringToTranslate) {

}

this converts string to resource id and use reflection to call resource
manager with this id.
This avoids changing all texts to cryptic names like MS recommends to
perform internationalization.

Is this possible and resonable ?




Andrus.
 
J

Jon Skeet [C# MVP]

Andrus said:
This would be interesting idea.
Should I use reflection to retrieve string value ?

No, there's no need. You've got the type, just use Name to get the type
name, and that's it. You don't need to do any further conversion.
 
J

Jon Skeet [C# MVP]

Andrus said:
Using resource ids insted of strings makes code unreadable since they tends
to be cryptic.

Do you have any idea how create method which converts string to valid C#
name (resource unique id).

E.q string like "Hello, world!" should be converted something like

Hello_44_32world_33

I don't think that's a good idea. It ties the purpose to the initial
value. I'd create a resource ID explaining what the resource is *used*
for, not one particular value. That way, if the wording changes but the
purpose doesn't, the ID is still relevant.
 
A

Andrus

Should I use reflection to retrieve string value ?
No, there's no need. You've got the type, just use Name to get the type
name, and that's it. You don't need to do any further conversion.

Should I create resources whose id is equal to type name ?
How to generate resource file automatically so that
resource ids are automatically created and only translations needs to be
entered ?

Andrus.
 
J

Jon Skeet [C# MVP]

Andrus said:
Should I create resources whose id is equal to type name ?

You could do. You might want to put typename ".Description" or
something to allow for multiple resources to do with the same type.
How to generate resource file automatically so that
resource ids are automatically created and only translations needs to be
entered ?

IIRC, the format of resx files is quite a simple one in XML. It
shouldn't be too hard to generate, particularly if you have a template
which you just insert entries into.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top