How to make readonly property in WCF? [duplicate] - c#

I have a server side class which I make available on the client side through a [DataContract]. This class has a readonly field which I'd like to make available through a property. However, I'm unable to do so because it doesn't seem that I'm allowed to add a [DataMember] property without having both get and set.
So - is there a way to have a [DataMember] property without setter?
[DataContract]
class SomeClass
{
private readonly int _id;
public SomeClass() { .. }
[DataMember]
public int Id { get { return _id; } }
[DataMember]
public string SomeString { get; set; }
}
Or will the solution be use the [DataMember] as the field - (like e.g. shown here)? Tried doing this too, but it doesn't seem to care the field is readonly..?
Edit: Is the only way to make a readonly property by hacking it like this? (no - I don't want to do this...)
[DataMember]
public int Id
{
get { return _id; }
private set { /* NOOP */ }
}

Your "server-side" class won't be "made available" to the client, really.
What happens is this: based on the data contract, the client will create a new separate class from the XML schema of the service. It cannot use the server-side class per se!
It will re-create a new class from the XML schema definition, but that schema doesn't contain any of the .NET specific things like visibility or access modifiers - it's just a XML schema, after all. The client-side class will be created in such a way that it has the same "footprint" on the wire - e.g. it serializes into the same XML format, basically.
You cannot "transport" .NET specific know-how about the class through a standard SOAP-based service - after all, all you're passing around are serialized messages - no classes!
Check the "Four tenets of SOA" (defined by Don Box of Microsoft):
Boundaries are explicit
Services are autonomous
Services share schema and contract, not class
Compability is based upon policy
See point #3 - services share schema and contract, not class - you only ever share the interface and XML schema for the data contract - that's all - no .NET classes.

put DataMember attribute on a field not the property.
Remember thought, that WCF does not know encapsulation. Encapsulation is a OOP term, not a SOA term.
That said, remember that the field will be readonly for people using your class - anyone using the service will have full access to the field on their side.

I had some properties in a class in my service layer I wanted to pass over to Silverlight. I didn't want to create a whole new class.
Not really 'recommended', but this seemed the lesser of two evils to pass over the Total property to silverlight (solely for visual databinding).
public class PricingSummary
{
public int TotalItemCount { get; set; } // doesnt ideally belong here but used by top bar when out of store area
public decimal SubTotal { get; set; }
public decimal? Taxes { get; set; }
public decimal Discount { get; set; }
public decimal? ShippingTotal { get; set; }
public decimal Total
{
get
{
return + SubTotal
+ (ShippingTotal ?? 0)
+ (Taxes ?? 0)
- Discount;
}
set
{
throw new ApplicationException("Cannot be set");
}
}
}

There is a way to achieve this. But be warned that it directly violates the following principle cited in this answer:
"3. Services share schema and contract, not class."
If this violation does not concern you, this is what you do:
Move the service and data contracts into a separate (portable) class library. (Let's call this assembly SomeService.Contracts.) This is how you'd define an immutable [DataContract] class:
namespace SomeService.Contracts
{
[DataContract]
public sealed class Foo
{
public Foo(int x)
{
this.x = x;
}
public int X
{
get
{
return x;
}
}
[DataMember] // NB: applied to the backing field, not to the property!
private readonly int x;
}
}
Note that [DataMember] is applied to the backing field, and not to the corresponding read-only property.
Reference the contract assembly from both your service application project (I'll call mine SomeService.Web) and from your client projects (mine is called SomeService.Client). This might result in the following project dependencies inside your solution:
Next, when you add the service reference to your client project, make sure to have the option "reuse types" enabled, and ensure that your contract assembly (SomeService.Contracts) will be included in this:
Voilà! Visual Studio, instead of generating a new Foo type from the service's WSDL schema, will reuse the immutable Foo type from your contract assembly.
One last warning: You've already strayed from the service principles cited in that other answer. But try not to stray any further. You might be tempted to start adding (business) logic to your data contract classes; don't. They should stay as close to dumb data transfer objects (DTOs) as you can manage.

Define the Service contract (Interface) Before implementing the contract using the class.

Related

Serializing a property from an Interface in Unity

So, I'm currently working on a strategy game that involves 3 types of buildings: "Production", "Storage", and "Refining".
Any building can belong to one or more of these types, so a Storage building could also be a Refining building and should then inherit the functionality of both of these types.
Example:
public class Stronghold : Building, IStorage, IRefining, IProduction
{
public RefiningOption[] RefiningOptions { get; set; }
}
public interface IRefining
{
public RefiningOption[] RefiningOptions { get; set; }
}
I went about implementing this using interfaces, but I am running into the issue that Unity does not allow you to serialize properties and interfaces can not contain fields.
Is there a way around this that would allow me to inherit from multiple different types in a neat way, or am I approaching this all wrong? I can think of a solution that would involve using separate components for the functionality of each building type, but before I implement that, I wanted to know what the "correct" solution would be.
Thanks in advance. I'm trying to expand my toolset, so any feedback is welcome.
Just like the answer above but in a more "compact" way
[field: SerializeField] public RefiningOption[] RefiningOptions { get; set; }
This is an auto-property that generates a backing field that you can access directly by typing [field: "Your_Attribute_Here"], this is the same as having a [Serialized] private field with a public property exposing it.
just like this ? create a field in private. and this private field can be serialize
private RefiningOption[] _refiningOptions;
public RefiningOption[] RefiningOptions
{
get { return _refiningOptions; }
set { _refiningOptions = value; }
}

MEF Metadata vs. Value

I'm a complete beginner here, so this might be a really obvious question, I just can't quite seem to understand or find an answer. I've read the MSDN example and most of it makes complete sense.
In the example, they define the following interfaces and give example usage like this;
public interface IOperation
{
int Operate(int left, int right);
}
public interface IOperationData
{
char Symbol { get; }
}
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '+')]
public class Add : IOperation
{
public int Operate(int left, int right)
{
return left + right;
}
}
I think I must be misunderstanding something here.
What's the point of IOperationData and ExportMetadata ?
Why can't I just drop them both and add char Symbol {get;} to IOperation ?
Then I could just use Add.Value.Symbol instead of Add.Metadata.Smybol. I guess that's not really a huge change, but it does mean I don't need ExportMetadata. What's the difference between Value and Metadata and why does the example use them like it does? Is Metadata for properties and Value for methods? It doesn't seem very well explained to me.
MEF allows composable parts to provide their metadata. Metadata here is a set of statically-known properties, which is typical for part type, not for the type instance.
Suppose you're building a GUI for calculator in the given example.
Each operation is a plugin here, which being loaded via MEF container. You don't want to instantiate every plugin until user selection, but you want to build the panel with buttons, where each button holds an operation symbol.
That's why you need to use metadata instead of adding char Symbol {get;} to IOperation:
you can access metadata without instantiation of part (this could be expensive);
the metadata belongs to the composable part, and every instance of that part should have the same metadata (although calculator example isn't a good choice for understanding that fact).
You're describing metadata interface IOperationData and applying ExportMetadata attribute to the composable part definition. Then, at run-time, MEF looks at Add class, and dynamically builds IOperationData implementation. The instance of that implementation being initialized with values, provided in ExportMetadata. And, finally, you can access the values of IOperationData implementation with Add.Metadata.Smybol later in host application.
UPDATE.
ExportMetadata allows you to add multiple metadata values, but it is often more convenient to add metadata, using custom attribute, which is inherited from ExportAttribute:
public interface IMyPlugin {}
public interface IMyMetadata
{
int Value1 { get; }
string Value2 { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MyExportAttribute : ExportAttribute, IMyMetadata
{
public MyExportAttribute(int value1, string value2)
: base(typeof(IMyPlugin))
{
Value1 = value1;
Value2 = value2;
}
public int Value1 { get; private set; }
public string Value2 { get; private set; }
}
Usage:
[MyExport(1, "Orange")]
public class MyPlugin : IMyPlugin {}

To abstract, or not to abstract

thanks in advance for reading this. I don’t fully understand how/when to use abstracts so I am trying to think about it each project I work on to see if it will all click some day Smile | :)
Also, the mix of accessibility levels (private, protected, internal) with keywords static, abstract, and override tend to leave me a little confused. How do I define this method/property/class....
It's not all a big mystery to me but some projects have me coding in circles when dealing with these topics.
With that said,
I have an application that reads an XML document and outputs text and image files. I’m also storing all of the information in a database. I have it working nicely.
The XML has a standard implementation with required fields and is used by multiple organizations to submit data to my app. All organizations should use (at least) the required nodes/elements that are outlined in the XML implementation guide.
So, I want to have a default data object type to be able to derive a specific organization’s data type for required elements. (If this object is going to be used, these are the fields that must be implemented).
If the org. just uses the default requirements, I can use the default object. If they use additional (optional) fields, I’ll have to create a new type inheriting the default type.
My first thought was to use and abstract class that had protected properties for my bare minimum requirements:
public abstract partial class AbstractDataObject
{
protected string DataObjectName;
protected DateTime? DataObjectDate;
etc...
}
Then, if the organization just uses the required elements of the node and no optional elements, I can use a “default” object.
internal partial class DefaultDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
}
But, if an organization uses optional fields of the required node, I can use a derived organization data object.
internal sealed partial class OranizationDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
Do I need the abstract class? It seems to me I can just have a DefaultDataObject (something like):
internal partial class DefaultDataObject
{
public virtual string DataObjectName { get; set; }
public virtual DateTime? DataObjectDate { get; set; }
etc...
}
And then:
internal sealed partial class OranizationDataObject : DefaultDataObject
{
public override string DataObjectName { get; set; }
public override DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
I’m just really trying to understand how to define these objects so I can reuse them per organization. Both ways seem to work, but I am hoping to understand how to define them properly.
Getting the XML into above objects:
public DefaultDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new DefaultDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate =
Program.TryParseDateTime((String)
t.Elements("ChildElement2")
.ElementAtOrDefault(0)
),
etc....
OR
public OranizationDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new OranizationDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate = Program.TryParseDateTime(
(String)t.Elements("ChildElement2")
.ElementAtOrDefault(0)),
DataObjectCode = (String)t.Element("ChildElement3"),
etc....
Again, thanks for reading. Don't forget to tip your wait staff....
Joe
First of all, your base class doesn't need to be abstract if it's a plain DTO class. If you don't have any functionality that needs to be implemented differently by derived classes, you can simply make it a plain base class which will hold common properties.
Next, there is no point in declaring properties in the base class (abstract in your case), if you are going to hide them (using the new keyword). You first code snippet of DefaultDataObject unnecessarily creates a bunch of new properties with the same name. Remove them completely - they are already defined in the base class.
[Edit] I didn't notice this initially, and #svick warned me, that your base class actually contained fields instead of properties, which makes me wonder why you needed to add the new keyword at all. I went over your code quickly and saw them as properties. In any case, you should never expose public fields - at least change them to auto-implemented properties by adding the { get; set; } block.
In other words, this would simply work:
// this doesn't need to be abstract.
// just put all the common stuff inside.
public class BaseDO
{
// as svick pointed out, these should also be properties.
// you should *never* expose public fields in your classes.
public string Name { get; set; }
public DateTime? Date { get; set; }
}
// don't use the new keyword to hide stuff.
// in most cases, you won't need that's behavior
public class DerivedDO : BaseDO
{
// no need to repeat those properties from above,
// only add **different ones**
public string Code { get; set; }
}
As a side note, but nevertheless important IMHO, you should simplify naming (and make it more clearer what your code does). There is no need to repeat "DataObject" in every property name, for example. But since your code is probably only a simplified version, it doesn't matter.
Lastly, have you heard of XmlSerializer? You don't need to traverse the XML elements manually. It is enough to call XmlSerializer to both serialize and deserialize your data.
Everything I need to know I learned from Sesame Street
Scrub your class design hard to make sure you've identified everything that is the same and different. Play computer, so to speak, with your classes and see how they do the same, different, or the same thing but in different ways.
What is the same, different, same but differently will likely change as you play computer.
Think in general terms of the two pillars of OO Classes. Polymorphism and Inheritance
As you do the above that is. Not so much in terms of C# implementation per se.
How things clump into same vs. different will help drive implementation
And it's all relative.
More of same default behavior? Perhaps a concrete base class instead of abstract.
More of same thing, but differently? Perhaps an abstract class instead of concrete base class.
A default way of doing x? Perhaps a virtual method.
Everyone does the same thing, but no two the same way? A delegate perhaps.
Implementation Suggestions
Make methods and fields protected as a default. Private does not get inherited. Designs change, stay flexible. If something just has to be private, fine.
virtual means you can change implementation in a sub class. It does not mean you must.
Folks seem to under-utilize delegates. They're super for polymorphic methods.
There is nothing wrong with public fields. What's the practical difference between a public field and a public auto-implemented property? Nothing. They both directly return (or set) the underlying value. So what's the point of even bothering with properties? If you want to publicly expose an underlying value differently than it's "natural" state. For example, returning a number in a specific format. And of course you can have different properties for the same field.
A Property can have a get without a set. Or vice versa. Also get and set can have different access levels. Often you'll see this as a public get and a protected (or private) set.
It depends on what the derived types will want to do. If they are going to use the default implementation and only expand on it somehow, then having the default class as the non-abstract base class is fine.
On the other hand, if they are most likely going to re-implement the functionality, you should have an abstract base class (or an interface) and a separate default class.
If you for some reason don't know which one is it, you can let the inheritors choose by having an abstract base class and leaving the default class unsealed.
Also, looking at your code, it seems you misunderstand what the various keywords do. Most of the time, you do not want to use new like this. What it does is to define another member with the same name, unrelated to the original one. Also, there's no reason to override something if you don't want to change it. So, if you expect that the derived classes won't have to reimplement the properties, you don't have to make them virtual at all.
An abstract class can already implement things that can be inherited
public abstract class DataObjectBase
{
public string DataObjectName { get; set; }
public DateTime? DataObjectDate { get; set; }
}
A concrete class can add new properties and methods
public class DerivedDataObject : DataObjectBase
{
public int NewProperty { get; set; }
}
The properties DataObjectName and DataObjectDate are already available in the new class, because they are automatically inherited from the base class.
If the abstract class defined an abstract member, however, you would have to implement it in the derived class.
Say the base class defines
public abstract void SomeMethod(string name);
The the derived class has to do this
public override void SomeMethod(string name)
{
...
}
If your base class does not have abstract members, it does not need to be abstract and can play the role of your default data object directly.
The keyword 'partial` is not needed here. It is only useful if you want to split one class into several pieces over several files.
The keyword new is wrong here. It is used to shadow an inherited member. This means that the inherited member will be hidden "behind" the new declaration. What you need, is to override. This does not hide a member, but provide an alternative implementation of the same member in the derived class.

Add an attribute to another assembly's class

Is it somehow possible to extend a type, wich is defined in another assembly, to add an attribute on one of its properties?
Exemple I have in assembly FooBar:
public class Foo
{
public string Bar { get; set; }
}
But in my UI assembly, I want to pass this type to a third party tool, and for this third party tool to work correctly I need the Bar property to have a specific attribute. This attribute is defined in the third party assembly, and I don't want a reference to this assembly in my FooBar assembly, since FooBar contains my domain an this is a UI tool.
You can't, if the thirdy-party tool uses standard reflection to get the attributes for your type.
You can, if the third-party tool uses the TypeDescriptor API to get the attributes for your type.
Sample code for the type descriptor case:
public class Foo
{
public string Bar { get; set; }
}
class FooMetadata
{
[Display(Name = "Bar")]
public string Bar { get; set; }
}
static void Main(string[] args)
{
PropertyDescriptorCollection properties;
AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider;
properties = TypeDescriptor.GetProperties(typeof(Foo));
Console.WriteLine(properties[0].Attributes.Count); // Prints X
typeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(
typeof(Foo),
typeof(FooMetadata));
TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, typeof(Foo));
properties = TypeDescriptor.GetProperties(typeof(Foo));
Console.WriteLine(properties[0].Attributes.Count); // Prints X+1
}
If you run this code you'll see that last console write prints plus one attribute because the Display attribute is now also being considered.
No. It's not possible to add attributes to types from separate assemblies.
What you can do, though, is create your own type that wraps the third-party type. Since you have full control over your wrapper class, you can add the attributes there.
What about:
public class Foo
{
public virtual string Bar
}
public class MyFoo : Foo
{
[yourcustomattribute]
public overrides string Bar
}
What I think you need is some kind of adapter layer that will not let that infrastructure dependency leak into your domain logic. Maybe you can create an adapter class that will be like a data transfer object to the other technology. This class lives in an integration assembly that has a dependency on the 3rd party library:
public class FooDTO {
[TheirAttribute]
public string Bar { get; set; }
}
You can then use something like AutoMapper to ease the pain of changing representations.
The ideal solution, though, is if the 3rd party library supported additional ways to provide metadata about their operations. Maybe you can ask them for this feature.

Anybody have a clever way to treat a DTO as more of an OO class?

I have a set of DataContracts that are serialzed through WCF.
Please note this is a very simplified example.
[DataContract]
public class MyData
{
[DataMember]
public List<int> MyList
{
get;
set;
}
}
I would like to use object oriented design so that the server and client aren't creating any unnecessary dependencies. For example, I would like to encapsulate a list so that the user can't directly modify it.
Ideally, I would like the class to look like this if it wasn't a DTO.
public class MyData
{
private List<int> _list = new List<int>();
public IEnumerable<int> MyList
{
get
{
return _list;
}
}
public void AddItem( int value )
{
_list.Add( value );
}
}
I am using the same C# assembly from both the service and the client. So I can add non-DataMember methods, but I'm not sure if that is a good approach. It doesn't smell quite right to me.
Does anybody have a clever way of treating DTO classes more like objects instead of simple serializable structures?
How about having DTO versions of your logic class which are used solely for the purpose of message passing?
That way, you can put all the methods and properties on your logic class as necessary without having to worry about what the user has access to when it's passed over the wire. There are many ways you can go about this, for instance:
you can implement some method on your logic class to return the DTO
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
public PlayerDTO ToTransport()
{
return new PlayerDTO { Name = Name, ... };
}
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
}
Or you can implement an explicit/implicit conversion
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
public static explicit operator PlayerDTO(Player player)
{
return new PlayerDTO { Name = player.Name, ... };
}
}
this lets you cast a Player object to PlayerDTO:
var player = new Player { Name = .... };
var dto = (PlayerDTO) player;
Personally, I do think having DataContract on objects which are for more than service operations is a bit of a smell, just as it would be for ORM column mappings. One somewhat limited way to make these DTOs more like true OO is to have your methods be extension methods of the DTO. You might need to do something creative if the OO version has state that needs to be captured between calls that is not inherent in the DTO object itself, though.
I do not think having methods unadorned by attributes in your DataContract's class necessarily smells. You have your service-oriented concerns on one hand (the operation and data contracts) and your object-oriented concerns on the other. What the client does with the provided data is of no concern to the service. The object-oriented issue you describe really only exists for the client.
If a client obtained Ball data from your service and it wants to Draw() it to the screen, whether or not the Ball class has a Draw() method has nothing to do with the contract between service and client. It is a contract between the api your assembly provides and those that use it. So I say, why not have a method in the assembly that is not an operation/data contract?

Categories

Resources