In WCF how do you put a datacontract on a class that has already been defined elsewhere? - wcf

So I have some class in a business logic .dll. It is not wrapped in a datacontract, I would like to expose it to anything calling the service by doing so in the Service and IService classes (for example). But the only examples I have seen have been to expose classes that are defined in the service, I do not wish to do this and I do not wish to use [Datacontract] in my business logic layer if that makes sense?
Ask if any clarification is required. Help is as always most appreciated.
Thanks :)
edit: I am slightly confused by many of these solutions, what I would like to do is provide the caller of the service a range of classes to instance and then pass back to the service through a method. So:
public Class ServiceConsumer{
addPerson(){
theService.addPerson(new theService.Person("Thomas", 22, "Male");
}
}
Does that make sense? That's a bit pseudo-codish as I can't remember the consumer side of WCF calls off the top of my head. All the solutions seem to require either knowledge of what classes are available or the classes mashed together in one class?
The only other solution I can see so far is to have a method for every class, but let me tell you there will be potentially a hundred classes!
Many thanks.

For starters, don't annotate the business object with [DataContract]. It's considered bad practice.
About 35 minutes into this video Miguel talks about data contracts.

What you need to use is a Data Transfer Object. It will make sure that there is proper separation between your Business Layer and the Service Layer. Also check this link.

While you should layer it properly, there are some cases where you dont really need the seperation of UI, Service, and Business Logic. Generally this happens when you are developing a smaller project, and its really not going to grow.
If you choose you still want to do this, see the example below. You are basically going to wrap your types in a Proxy like "RequestContract" In my case my BL types would be MyType and ByMyType. Those two classes are not annotated and they are brought in using DataContracts defined in the service.
public class ExampleService : IExampleService
{
public ExampleService() { }
public GetMyTypeResponseContract GetMyType(GetMyTypeRequestContract theType)
{
return new GetMyTypeResponseContract()
{
MyType = new MyType()
{
Response = theType.ByMyType.Request
}
};
}
}
[DataContract]
public class GetMyTypeRequestContract
{
[DataMember]
public ByMyType ByMyType { get; set; }
public GetMyTypeRequestContract() { }
}
[DataContract]
public class GetMyTypeResponseContract
{
[DataMember]
public MyType MyType { get; set; }
public GetMyTypeResponseContract() { }
}

Have you considered using POCO - http://msdn.microsoft.com/en-us/library/ee705457.aspx

From a technology point of view, you can use a surrogate.

Related

Do we need interfaces for dependency injection?

I have an ASP.NET Core application. The application has few helper classes that does some work. Each class has different signature method. I see lot of .net core examples online that create interface for each class and then register types with DI framework. For example
public interface IStorage
{
Task Download(string file);
}
public class Storage
{
public Task Download(string file)
{
}
}
public interface IOcr
{
Task Process();
}
public class Ocr:IOcr
{
public Task Process()
{
}
}
Basically for each interface there is only one class. Then i register these types with DI as
services.AddScoped<IStorage, Storage>();
services.AddScoped<IOcr,Ocr>();
But i can register type without having interfaces so interfaces here look redundant. eg
services.AddScoped<Storage>();
services.AddScoped<Ocr>();
So do i really need interfaces?
No, you don't need interfaces for dependency injection. But dependency injection is much more useful with them!
As you noticed, you can register concrete types with the service collection and ASP.NET Core will inject them into your classes without problems. The benefit you get by injecting them over simply creating instances with new Storage() is service lifetime management (transient vs. scoped vs. singleton).
That's useful, but only part of the power of using DI. As #DavidG pointed out, the big reason why interfaces are so often paired with DI is because of testing. Making your consumer classes depend on interfaces (abstractions) instead of other concrete classes makes them much easier to test.
For example, you could create a MockStorage that implements IStorage for use during testing, and your consumer class shouldn't be able to tell the difference. Or, you can use a mocking framework to easily create a mocked IStorage on the fly. Doing the same thing with concrete classes is much harder. Interfaces make it easy to replace implementations without changing the abstraction.
Does it work? Yes. Should you do it? No.
Dependency Injection is a tool for the principle of Dependency Inversion : https://en.wikipedia.org/wiki/Dependency_inversion_principle
Or as it's described in SOLID
one should “depend upon abstractions, [not] concretions."
You can just inject concrete classes all over the place and it will work. But it's not what DI was designed to achieve.
No, we don't need interfaces. In addition to injecting classes or interfaces you can also inject delegates. It's comparable to injecting an interface with one method.
Example:
public delegate int DoMathFunction(int value1, int value2);
public class DependsOnMathFunction
{
private readonly DoMathFunction _doMath;
public DependsOnAFunction(DoMathFunction doMath)
{
_doMath = doMath;
}
public int DoSomethingWithNumbers(int number1, int number2)
{
return _doMath(number1, number2);
}
}
You could do it without declaring a delegate, just injecting a Func<Something, Whatever> and that will also work. I'd lean toward the delegate because it's easier to set up DI. You might have two delegates with the same signature that serve unrelated purposes.
One benefit to this is that it steers the code toward interface segregation. Someone might be tempted to add a method to an interface (and its implementation) because it's already getting injected somewhere so it's convenient.
That means
The interface and implementation gain responsibility they possibly shouldn't have just because it's convenient for someone in the moment.
The class that depends on the interface can also grow in its responsibility but it's harder to identify because the number of its dependencies hasn't grown.
Other classes end up depending on the bloated, less-segregated interface.
I've seen cases where a single dependency eventually grows into what should really be two or three entirely separate classes, all because it was convenient to add to an existing interface and class instead of injecting something new. That in turn helped some classes on their way to becoming 2,500 lines long.
You can't prevent someone doing what they shouldn't. You can't stop someone from just making a class depend on 10 different delegates. But it can set a pattern that guides future growth in the right direction and provides some resistance to growing interfaces and classes out control.
(This doesn't mean don't use interfaces. It means that you have options.)
I won't try to cover what others have already mentioned, using interfaces with DI will often be the best option. But it's worth mentioning that using object inheritance at times may provide another useful option. So for example:
public class Storage
{
public virtual Task Download(string file)
{
}
}
public class DiskStorage: Storage
{
public override Task Download(string file)
{
}
}
and registering it like so:
services.AddScoped<Storage, DiskStorage>();
Without Interface
public class Benefits
{
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : Benefits
{
private readonly Benefits BT;
public Teacher(Benefits _BT)
{ BT = _BT; }
public void TeacherBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
public class Student : Benefits
{
private readonly Benefits BS;
public Student(Benefits _BS)
{ BS = _BS; }
public void StudentBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
here you can see benefits for Teachers is accessible in Student class and benefits for Student is accessible in Teacher class which is wrong.
Lets see how can we resolve this problem using interface
With Interface
public interface IBenefitForTeacher
{
void BenefitForTeacher();
}
public interface IBenefitForStudent
{
void BenefitForStudent();
}
public class Benefits : IBenefitForTeacher, IBenefitForStudent
{
public Benefits() { }
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : IBenefitForTeacher
{
private readonly IBenefitForTeacher BT;
public Teacher(IBenefitForTeacher _BT)
{ BT = _BT; }
public void BenefitForTeacher()
{
BT.BenefitForTeacher();
}
}
public class Student : IBenefitForStudent
{
private readonly IBenefitForStudent BS;
public Student(IBenefitForStudent _BS)
{ BS = _BS; }
public void BenefitForStudent()
{
BS.BenefitForStudent();
}
}
Here you can see there is no way to call Teacher benefits in Student class and Student benefits in Teacher class
So interface is used here as an abstraction layer.

When is an "interface" useful?

OOP interfaces.
In my own experience I find interfaces very useful when it comes to design and implement multiple inter-operating modules with multiple developers. For example, if there are two developers, one working on backend and other on frontend (UI) then they can start working in parallel once they have interfaces finalized. Thus, if everyone follows the defined contract then the integration later becomes painless. And thats what interfaces precisely do - define the contract!
Basically it avoids this situation :
Interfaces are very useful when you need a class to operate on generic methods implemented by subclasses.
public class Person
{
public void Eat(IFruit fruit)
{
Console.WriteLine("The {0} is delicious!",fruit.Name);
}
}
public interface IFruit
{
string Name { get; }
}
public class Apple : IFruit
{
public string Name
{
get { return "Apple"; }
}
}
public class Strawberry : IFruit
{
public string Name
{
get { return "Strawberry"; }
}
}
Interfaces are very useful, in case of multiple inheritance.
An Interface totally abstracts away the implementation knowledge from the client.
It allows us to change their behavior dynamically. This means how it will act depends on dynamic specialization (or substitution).
It prevents the client from being broken if the developer made some changes
to implementation or added new specialization/implementation.
It gives an open way to extend an implementation.
Programming language (C#, java )
These languages do not support multiple inheritance from classes, however, they do support multiple inheritance from interfaces; this is yet another advantage of an interface.
Basically Interfaces allow a Program to change the Implementation without having to tell all clients that they now need a "Bar" Object instead of a "Foo" Object. It tells the users of this class what it does, not what it is.
Example:
A Method you wrote wants to loop through the values given to it. Now there are several things you can iterate over, like Lists, Arrays and Collections.
Without Interfaces you would have to write:
public class Foo<T>
{
public void DoSomething(T items[])
{
}
public void DoSomething(List<T> items)
{
}
public void DoSomething(SomeCollectionType<T> items)
{
}
}
And for every new iteratable type you'd have to add another method or the user of your class would have to cast his data. For example with this solution if he has a Collection of FooCollectionType he has to cast it to an Array, List or SomeOtherCollectionType.
With interfaces you only need:
public class Foo<T>
{
public void DoSomething(IEnumerable<T> items)
{
}
}
This means your class only has to know that, whatever the user passes to it can be iterated over. If the user changes his SomeCollectionType to AnotherCollectionType he neither has to cast nor change your class.
Take note that abstract base classes allow for the same sort of abstraction but have some slight differences in usage.

WCF method that updates object passed in

Am I correct in thinking that if I have a WCF OperationContract takes in an object and needs to set a property on that object so the client gets the update, I need to declare it to return the object.
e.g. given a datacontract:
[DataContract]
public class CompositeType
{
[DataMember]
public int Key { get; set; }
[DataMember]
public string Something { get; set; }
}
this will not work with WCF:
public void GetDataUsingDataContract(CompositeType composite)
{
composite.Key = 42;
}
this will work:
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
composite.Key = 42;
return new CompositeType
{
Key = composite.Key,
Something = composite.Something
};
}
IMO, authoring methods that produce output via side-effects is a "bad" thing. Having said that however, are there circumstances that necessitate this model? Yes.
Certainly C# programming model permits this, is WCF broken? No. At a certain point, one must realise they are consuming WCF, and as a framework it attempts to satisfy a majority of use-cases [for instance, replicating all input parameters on all round trips to preserve implicit side effect semantics is, in a word, silly].
Of course, there are ways to work around this - C# also provides for explicit declaration of these scenarios and WCF supports these as well!
For instance
// use of "ref" indicates argument should be returned to
// caller, black-eye and all!
public void GetDataUsingDataContract (ref CompositeType composite)
{
composite.Key = 42;
}
Give it a go!
Hope this helps :)
If you use 'out of the box' WCF, you are actually using a form of webservices, that uses serialized versions of the objects that are sent from client to server.
This is the reason you cannot 'by reference' change properties on objects. You will always have to use a request / response pattern.

WCF DataContract Upcasting

I'm trying to take a datacontract object that I received on the server, do some manipulation on it and then return an upcasted version of it however it doesn't seem to be working. I can get it to work by using the KnownType or ServiceKnownType attributes, but I don't want to roundtrip all of the data. Below is an example:
[DataContract]
public class MyBaseObject
{
[DataMember]
public int Id { get; set; }
}
[DataContract]
public class MyDerivedObject : MyBaseObject
{
[DataMember]
public string Name { get; set; }
}
[ServiceContract(Namespace = "http://My.Web.Service")]
public interface IServiceProvider
{
[OperationContract]
List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects);
}
public class ServiceProvider : IServiceProvider
{
public List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects)
{
... do some work ...
myDerivedObjects[0].Id = 123;
myDerivedObjects[1].Id = 456;
myDerivedObjects[2].Id = 789;
... do some work ...
return myDerivedObjects.Cast<MyBaseObject>().ToList();
}
}
Anybody have any ideas how to get this to work without having to recreate new objects or using the KnownType attributes?
I think that your problem is that you are trying to send over a generic list.
It will work if you encapsulate the list in an object. That is create an object with a single public property which is the generic list.
You also need to make sure that all classes that are not used directly in the contract are marked as serializable.
If you want to return the derived objects then there will always be a round trip because the client and the service are separate. In order for the client to update its own list of MyBaseObjects it has to deserialize the list of MyDerivedObjects that came from the server.
The use of KnownType and/or ServiceKnownType is needed because this leads to the addition of that type information into WSDL, which is in turn used by the client to deserialize the messages to the correct type.
For starters, a useful tool for testing the scenario you've described: http://www.wcfstorm.com
You might try creating a DataContractSurrogate (IDataContractSurrogate) and returning your base type for the call to GetDataContractType. I'm not really sure that's how it was intended to be used so you still may be better of with "the extra work", but maybe I don't understand the scope of that extra work.
One of the problems with WCF (and .net remoting) is that it they tries to make “message passing” look like method calls.
This fall down when you try to use too many “oop” type designs.
The fact that the messages are
represented by .net classes, does not
make all of their behaviour like .net
class.
See this, and this, for more on the problem of Leaking Abstraction.
So you need to start thinking about message passing not object when designing your WCF interfaces, or you will hit lots of problems like this.

Is it possible to serialize objects without a parameterless constructor in WCF?

I know that a private parameterless constructor works but what about an object with no parameterless constructors?
I would like to expose types from a third party library so I have no control over the type definitions.
If there is a way what is the easiest? E.g. I don't what to have to create a sub type.
Edit:
What I'm looking for is something like the level of customization shown here: http://msdn.microsoft.com/en-us/magazine/cc163902.aspx
although I don't want to have to resort to streams to serialize/deserialize.
You can't really make arbitrary types serializable; in some cases (XmlSerializer, for example) the runtime exposes options to spoof the attributes. But DataContractSerializer doesn't allow this. Feasible options:
hide the classes behind your own types that are serializable (lots of work)
provide binary formatter surrogates (yeuch)
write your own serialization core (a lot of work to get right)
Essentially, if something isn't designed for serialization, very little of the framework will let you serialize it.
I just ran a little test, using a WCF Service that returns an basic object that does not have a default constructor.
//[DataContract]
//[Serializable]
public class MyObject
{
public MyObject(string _name)
{
Name = _name;
}
//[DataMember]
public string Name { get; set; }
//[DataMember]
public string Address { get; set; }
}
Here is what the service looks like:
public class MyService : IMyService
{
#region IMyService Members
public MyObject GetByName(string _name)
{
return new MyObject(_name) { Address = "Test Address" };
}
#endregion
}
This actually works, as long as MyObject is either a [DataContract] or [Serializable]. Interestingly, it doesn't seem to need the default constructor on the client side. There is a related post here:
How does WCF deserialization instantiate objects without calling a constructor?
I am not a WCF expert but it is unlikely that they support serialization on a constructor with arbitrary types. Namely because what would they pass in for values? You could pass null for reference types and empty values for structs. But what good would a type be that could be constructed with completely empty data?
I think you are stuck with 1 of 2 options
Sub class the type in question and pass appropriate default values to the non-parameterless constructor
Create a type that exists soley for serialization. Once completed it can create an instance of the original type that you are interested in. It is a bridge of sorts.
Personally I would go for #2. Make the class a data only structure and optimize it for serialization and factory purposes.