Is it a good idea to create private data members in WCF service and if it is a good practice then when/where we initilize these member variable as the client is only calling methods of the service.
Use your data contracts merely as DTO's, and extend these in the code that does the processing of the data.
Something like this:
[DataContract]
public class WCFDataClass
{
[DataMember]
public String Foo { get; set; }
}
// Your class, used for internal processing
class MyWCFDataClass : WCFDataClass
{
public String MyFoo { get; set; }
public String DoFoo()
{
return this.Foo + this.MyFoo;
}
}
If you have any interest in interoperability, I dont't believe it is generally a good practice.
First a contract (operation contract, message contract, data contract , etc.) is created to specify, in an unambiguous way, what is supported and what is not. It explicitly specifies those things publicly. It gets very confusing, very quickly, when you start declaring private members to be part of a public contract. It becomes problematic for the programmer who comes after you to discern what is going on.
You are likely attempting to encapsulate logic in your data contracts, which is not the purpose of a data contract. As suggested by #CodeCaster, such manipulation should be performed outside the data contract class. Even simple things like constructors populating default values can be problematic. Such logic should also be performed outside the DataContract class.
In addition, when you declare private members to be [DataMember]s you are relying on a non-standard implementation detail of the data contract serialiser - the fact that it can read/write members that are not public - i.e. the DataConstractSerializer (at least on the .NET platform) can do things you couldn't do in your own code. You are depending on 'magic'. While this 'magic' helps DataConstractSerializer to deliver amazing performance, I don't think you should be depending on its implementation details. For example, you will find that such DataContract classes cannot be shared with Silverlight applications because on that platform the DataConstractSerializer cannot read/write non-public members.
However, like all 'practices', you have to consider your circumstances. If interoperability and maintainability are not a requirement, then most of the above is not relevant and can be disregarded. :)
Related
I came across an interface recently that only defined a setter like so:
public interface IAggregationView
{
DataTable SetSiteData { set; }
}
I queried this, and it is believed that this is one of the practices advocated by Microsoft for WebPart design (for SharePoint). In fact this example is directly copied from their examples.
I see this as a bad pattern, I don't see why someone should be able to set a value, and then not be able to read it again, and I believe a setter should always be accompanied with a getter (but not necessarily the other way around).
I'm wondering if anyone can explain the benefit of only having a setter, why Microsoft might be suggesting it in this case, and if it's really a good pattern to be following?
There are two scenarios I can see where this might be reasonable:
it is not possible get the value, for example a password; however, I would replace that with a void SetPassword(string) method, personally
the API it is designed for has no requirement to ever read the value, and it is being restricted purely to expose the minimum required API
Re my first point, a Set... method may not be ideal if the consuming API is essentially an automated mapper that assigns values to properties; in that scenario properties would indeed be preferable.
Re your "I don't see why someone should be able to set a value, and then not be able to read it again" - by the same point, however, it could be argued that someone setting the value already knows the value (they set it), so they have no requirement to do this.
But yes; it is very unusual to have a set-only property.
The role of get and set in interface properties is slightly different from those in classes.
public interface IAggregationView
{
DataTable SetSiteData { set; }
}
class AggregationViewImp : IAggregationView
{
public DataTable SetSiteData { get; set; } // perfectly OK
}
The interface specifies that the property should at least have a public setter. The definition and accessibility of the getter is left to the implementing class.
So if the interface contract only needs to write, get can be left open. No need to demand a public getter.
As a consequence, you cannot really specify a read-only property in interfaces either. Only 'at least read access'.
interface IFoo
{
int Id { get; }
}
class Foo : IFoo
{
public int Id { get; set; } // protected/private set is OK too
}
I can imagine using it for (manual) dependency injection. A class may need to have a collaborator injected that it only uses internally. Of course one would normally choose to do this in the class' constructor, but there may be times when one would wish to change the collaborator at runtime.
Classes that implement the interface may add a getter. Most uses of the property may be via an implementing class, not via the interface itself. In which case most code has the ability to get and set the property. The only reason for the interface may be that there is some common code that accesses a common subset of the methods/properties of a family of classes. That code only requires the setter, not the getter. The interface documents that fact.
An interface is just a facility for declaring a group of operations that are "atomically needed" (e.g. if you need to call method A, you'll need to read property B and set property C).
So as always, it depends.
In my experiences such interfaces crop up due to some special need, not for architectural reasons. For example in ASP.NET applications people sometimes make the Global.asax generated type derive from such an interface when they want to maintain global state. Someone might create an initialization value in a separate part of the application and need to publish it to a global place.
I usually like to replace a set-only property with a SetXxx method and make the method check that it is called at most once. That way I clearly enforce "initialization style" which is much less of a smell (imho).
Certainly one cannot set to never produce such a thing but it is to be avoided and will certainly raise questions during code review.
I need to create some DTO classes to transport our business objects across WCF.
Since these are just bags of data with no functionality, is there any reason I can't just use fields, or is there some good reason to expose them properly as properties?
//fields
[DataContract]
class CustomerDTO
{
[DataMember] public int Id;
[DataMember] public string Name;
}
//or properties?
[DataContract]
class CustomerDTO
{
[DataMember] public int Id { get; set; }
[DataMember] public string Name { get; set; }
}
I mostly favour immutable DTOs with read-only fields if I can get away with it:
public class CustomerDTO
{
public CustomerDTO(int id, string name)
{
Id = id;
Name = name;
}
public readonly int Id;
public readonly string Name;
// Override Equals and GetHashCode as well...
}
There's lots of advantages to be had from immutable records, such as structural equality, which makes automated test assertions much simpler to write. It also dispenses with the need to write and maintain separate Test Data Builders.
It depends on the serializer, though. JSON.NET can handle immutable records, but many other serializers can't.
For those that handle public fields, I prefer fields over properties, simply because it's more honest; automatically implemented read/write properties provide no encapsulation.
Some serializers insist on public properties, and don't serialize fields. If that's the scenario, you have to go with that.
Honestly, considering how much thought I've put into this, it's not really something that keeps me awake at night, because ultimately, at the boundaries, applications aren't object-oriented. Thus, the rules of OOD don't really apply to DTOs anyway.
Since these are just bags of data with no functionality, is there any reason I can't just use fields
There are no strong arguments against public fields here. But do realize that it is only because there is no logic (behaviour) inside the DTOs so that the normal argument of encapsulation doesn't hold.
I would still prefer properties but they're not really necessary here.
You can use either. Since it doesn't affect performance, you'd be safer off going with properties in case you run into some serialization framework or similar that doesn't work with public fields.
Note that WCF proxy generation will create those DTOs on the client side with public properties and their backing private fields, even if you use public fields on the service side. If you somehow don't want that, you need to share a DTO library between the service and the client.
The DataMember attribute will work with both public fields and properties, so either would be possible. However, I would recommend sticking with properties.
In particular, if you are using StyleCop, then you would be breaking rule SA1401.
The reason for this rule's existence doesn't really apply in your case, but it would still be a maintenance problem if you are running StyleCop validation as part of a build on a continuous integration server.
Here are two advantages of properties over fields that I didn't see anyone else mention.
Friction in syntax properly matches capabilities
I think the default behavior should be the safer option. For fields, the default behavior allows for mutability, which is the more dangerous option. The keyword readonly must be added to make a field immutable (outside of constructors). In contrast, the default state of an auto property is immutable; the syntax set; must be added in order for the property to be mutable (outside of constructors).
Reference count given in Visual Studio's Code Lens
Unlike a field, viewing a property in Visual Studio has a "Code Lens", which includes its reference count. I am able to understand and refactor a property more quickly than a field because of this additional information. Of course, one can search in Visual Studio for references to things like fields and properties using Shift+F12, but that is an extra step that takes time. Moreover, in rare cases, some projects include multiple targets. This makes the Shift+F12 search results more difficult to use because there is a search is performed for every target. In contract, the reference count given in a property's Code Len is independent of the number of project targets.
Conclusion
To directly answer the question though, I prefer to use mutable properties (and no explicit constructors) in order to ensure I will be using the happiest of happy paths in the serialization library (which was mentioned in the answer of #ErenErsönmez).
I'd never expose fields directly, most companies prohibit this in their standards. Effectively you totally throw away encapsulation. DTOs, being anemic representations of something more complex are an odd case as their properties pretty much break encapsulation anyway. Personally, I'd use the properties as that's what they're there for. It also lets you implement "dirty" functionality etc. if you need to which isn't so easy if you're tweaking fields directly.
When you make a new WCF project, sample service is generated for you. The default data contract is (I've just changed the string type field title):
[DataContract]
public class CompositeType
{
bool boolValue = true;
string name = "";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
What is the point of having those private fields boolValue and name? Is it a good practice writing some data sanitizing or some other manipulations in contract, thus bloating it? It seems the only sane reason for me not writing to fields directly. So is it a bloatware or it has some reason behind it?
In my opinion, DataContracts singular purpose should be to transfer data between domains. Validation/sanitizing logic should be outside the DataContract's responsibilities. Especially if the intent is to share/link the code file in multiple projects/platforms for reuse.
This also implies that you shouldn't have your DataContract object used elsewhere in your application. It should go through some kind of adapter or converter to read/write the content to your application-specific objects. Its in that conversion (or your application objects) where you can do some validation. The simpler your data-transfer layer the better.
Plausibly, you might add logging/debugging code in the setters/getters (preferably temporarily) to track data input/output as needed. So far, that's the only case I've felt OK to put anything other than simple properties in a DataContract object (and again, I only did so temporarily).
EDIT: As to why this is the default generated file, I'm not sure. My DataContract objects are always using automatic properties. I'd suggest maybe this was a throwback to .NET 2.0 before automatic properties were introduced, but WCF/DataContracts weren't introduced until 3.0 anyway.
The same reason you ever write a getter and setter for any private value, to help aid encapsulation and allow you to manipulate the inner workings of your class without having to worry about outside members breaking since they were manipulating variables directly.
The short answer is that the public properties allow you, the designer, to restrict the values before they can be assigned to your private fields, potentially saving you from dealing with unexpected data. Although most get and set methods are the same, they are frequently the first line of defense against bad data.
I am newbie to SOA though I have some experience in OOAD.
One of the guidelines for SOA design is “Use Abstract Classes for Modeling only. Omit them from Design”. The use of abstraction can be helpful in modeling (analysis phase).
During analysis phase I have come up with a BankAccount base class. The specialized classes derived from it are “FixedAccount” and “SavingsAccount”. I need to create a service that will return all accounts (list of accounts) for a user. What should be the structure of service(s) to meet the requirement?
Note: It would be great if you can provide code demonstration using WCF.
It sounds like you are trying to use SOA to remotely access your object model. You would be better of looking at the interactions and capabilities you want your service to expose and avoid exposing inheritance details of your services implementation.
So in this instance where you need a list of user accounts your interface would look something like
[ServiceContract]
interface ISomeService
{
[OperationContract]
Collection<AccountSummary> ListAccountsForUser(
User user /*This information could be out of band in a claim*/);
}
[DataContract]
class AccountSummary
{
[DataMember]
public string AccountNumber {get;set;}
[DataMember]
public string AccountType {get;set;}
//Other account summary information
}
if you do decide to go down the inheritance route, you can use the KnownType attribute, but be aware that this will add some type information into the message being sent across the wire which may limit your interoperability in some cases.
Update:
I was a bit limited for time earlier when I answered, so I'll try and elaborate on why I prefer this style.
I would not advise exposing your OOAD via DTOs in a seperate layer this usually leads to a bloated interface where you pass around a lot of data that isn't used and religously map it into and out of what is essentially a copy of your domain model with all the logic deleted, and I just don't see the value. I usually design my service layer around the operations that it exposes and I use DTOs for the definition of the service interactions.
Using DTOs based on exposed operations and not on the domain model helps keep the service encapsulation and reduces coupling to the domain model. By not exposing my domain model, I don't have to make any compromises on field visibility or inheritance for the sake of serialization.
for example if I was exposing a Transfer method from one account to another the service interface would look something like this:
[ServiceContract]
interface ISomeService
{
[OperationContract]
TransferResult Transfer(TransferRequest request);
}
[DataContract]
class TransferRequest
{
[DataMember]
public string FromAccountNumber {get;set;}
[DataMember]
public string ToAccountNumber {get;set;}
[DataMember]
public Money Amount {get;set;}
}
class SomeService : ISomeService
{
TransferResult Transfer(TransferRequest request)
{
//Check parameters...omitted for clarity
var from = repository.Load<Account>(request.FromAccountNumber);
//Assert that the caller is authorised to request transfer on this account
var to = repository.Load<Account>(request.ToAccountNumber);
from.Transfer(to, request.Amount);
//Build an appropriate response (or fault)
}
}
now from this interface it is very clear to the conusmer what the required data to call this operation is. If I implemented this as
[ServiceContract]
interface ISomeService
{
[OperationContract]
TransferResult Transfer(AccountDto from, AccountDto to, MoneyDto dto);
}
and AccountDto is a copy of the fields in account, as a consumer, which fields should I populate? All of them? If a new property is added to support a new operation, all users of all operations can now see this property. WCF allows me to mark this property as non mandatory so that I don't break all of my other clients, but if it is mandatory to the new operation the client will only find out when they call the operation.
Worse, as the service implementer, what happens if they have provided me with a current balance? should I trust it?
The general rule here is to ask who owns the data, the client or the service? If the client owns it, then it can pass it to the service and after doing some basic checks, the service can use it. If the service owns it, the client should only pass enough information for the service to retrieve what it needs. This allows the service to maintain the consistency of the data that it owns.
In this example, the service owns the account information and the key to locate it is an account number. While the service may validate the amount (is positive, supported currency etc.) this is owned by the client and therefore we expect all fields on the DTO to be populated.
In summary, I have seen it done all 3 ways, but designing DTOs around specific operations has been by far the most successful both from service and consumer implementations. It allows operations to evolve independently and is very explicit about what is expected by the service and what will be returned to the client.
I would go pretty much with what others have said here, but probably needs to add these:
Most SOA systems use Web Services for communication. Web Services expose their interface via WSDL. WSDL does not have any understanding of inheritance.
All behaviour in your DTOs will be lost when they cross the wire
All private/protected fields will be lost when they cross the wire
Imagine this scenario (case is silly but illustrative):
public abstract class BankAccount
{
private DateTime _creationDate = DateTime.Now;
public DateTime CreationDate
{
get { return _creationDate; }
set { _creationDate = value; }
}
public virtual string CreationDateUniversal
{
get { return _creationDate.ToUniversalTime().ToString(); }
}
}
public class SavingAccount : BankAccount
{
public override string CreationDateUniversal
{
get
{
return base.CreationDateUniversal + " UTC";
}
}
}
And now you have used "Add Service Reference" or "Add Web Reference" on your client (and not re-use of the assemblies) to access the the saving account.
SavingAccount account = serviceProxy.GetSavingAccountById(id);
account.CreationDate = DateTime.Now;
var creationDateUniversal = account.CreationDateUniversal; // out of sync!!
What is going to happen is the changes to the CreationDate will not be reciprocated to the CreationDateUniversal since there is no implementation crossed the wire, only the value of CreationDateUniversal at the time of serialization at the server.
Even if I make class member functions public and it is consumed by
other client applications, implementation details of
functions will never get exposed to client. Why make member functions protected or private?
For example, if my class is Math, with public function sum(int, int b) then only interface/declaration part will be exposed to client and not implementation.
public class Math
{
public int sum(int, int b)
{
//Implementation
}
}
public class Client
{
Math objMath = new Math();
objMath.Sum(4,10);//It will not display implementation inside sum than why to avoid
}
The more public your methods (and types) are, the more code they're exposed to. That increases the chance that other code (even code under your company's control) will start depending on that code working the way it currently does... which limits the flexibility to change the implementation later.
To give a concrete example, I'm working on an open source project called Noda Time. Now admittedly we haven't had our first public release yet, but I've recently been making a load of changes to various internal types - including changing the type hierarchies fairly significantly, and even removing methods. If those had been public types or public methods (and if we'd already gone to v1.0) then we could have broken code which depended on that specific implementation.
By hiding everything you don't know to be useful to clients, you buy yourself a lot of flexibility. It's incredibly important to put a lot of thought into your public API, because that's really hard to change later - but if you've kept a lot of your implementation internal, you can refactor to your heart's content to make it more elegant, more flexible, or perhaps faster... all without breaking any of the code depending on your library.
Obviously some things need to be exposed - at least in class libraries - but you should be careful just how much you expose, unless you're happy to break all callers later on (or live with every decision you make, forever).
There's nothing wrong with public member functions- they're quite essential, although the necessity of an object in your case is more than somewhat dubious. However, protected/private functions are for when you need to re-use some code that shouldn't be part of the public interface.
Because some methods may be part of internal implementation, and not of public interface. For example, some private method can change state of object to invalid one, but it is only used as intermediate step in some other public method. Definetely you don't want it to be called by client.