First of all, the requirement : I need to send .net objects over the network. Here is a basic structure of the class -
class something : somethingelse
{
public int count { get; set; }
public List<object> items { get; set; }
public something(string name)
{
//some initialization
}
public object Evaluate(string type)
{
//some logic
}
}
The something class have many different implementation on the server, all derived from an Interface (hence, they have same structure). However, in each of them, the logic inside the Evaluate method changes. Client application have no idea about the implementations beforehand. What we need is that server will send an object to the client, based on an identifier in the client request, and client will use that object to evaluate the data further.
What I already tried:
Basic .net serialization : It seems they do serialize only the state of the object (data members), not the actual object. To use the methods, I need to have the DLL referenced at the client-side. But as I mentioned, client should have no idea about the implementations beforehand.
.NET remoting : I believe this has become an obsolete tech. I would not prefer to build a whole new app based on it.
WCF : I could not find if it fits in, for the same reason as #1
gRPC with Protocol Buffer : I did look into it specifically because it seems to be faster (and we have plans to create large objects). However, I could not figure out a similar way to serialize a whole object, instead of only data members.
Any help any any direction would be greatly appreciated.
Related
I know this might be an opinion-based question, but, I'd rather to ask as there might be some design principle for this.
I'm having a .net C# web API application to expose few APIs to retrieve some data from a database. I'm also using mediateR on this project. The APIs, they all get one request object but all of them have exact same properties. Imagine, we have a BaseProduct class from which ProductA, ProductB, and ProductChave been inherited in the domain project. Now, I need to expose APIs to return these three objects to the users. Here's an example of two of the request objects.
With Inheritance:
public abstract class BaseGetProductRequest { // the props here }
public class GetProductARequest : BaseGetProductRequest, IRequest<GetProductAResponse> { }
public class GetProductBRequest : BaseGetProductRequest, IRequest<GetProductBResponse> { }
public class GetProductAResponse { public ProductA[] Products {get; set;} }
Each of the above requests also has its own request handler class.
With using generics: (BaseProduct is a domain object class from which different product types are inherited)
public class GetProductRequest<TProductType> : IRequest<TProductType[]> where TProductType : BaseProductType { // all props in here }
Which will be used like this in an API:
public async Task<ProductA[]> Get([FromRoute] GetProductRequest<ProductA> request) { // API body }
So, the question is: Which one the following would be a better approach to take from a design point of view?
To take the Inheritance approach as above
Or to implement the requests and request handlers using generics so we'll end up with less files
Personally, I would prefer the first approach as I want to literally have separate request objects for each API, this way it looks cleaner to me besides that would be consistent with the rest of the code as well (as not all the request objects can be implemented generically). Besides, if by any chance in the future there is a need to add a type-specific property for a request object, then, our code will be more flexible with that change.
Is there like any specific design guidelines which recommends for example taking one over another? Thanks for your opinions in advance.
Sure the inheritance approach will give your project a higher performance, due to the re-usability of compiled requests
Previous Post removed; Updated:
So I have a unique issue, which is possibly fairly common though. Properties are quite possibly are most commonly used code; as it requires our data to keep a constant value storage. So I thought how could I implement this; then I thought about how easy Generics can make life. Unfortunately we can't just use a Property in a Generic without some heavy legwork. So here was my solution / problem; as I'm not sure it is the best method- That is why I was seeking review from my peers.
Keep in mind the application will be massive; this is a very simple example.
Abstract:
Presentation Layer: The interface will have a series of fields; or even data to go across the wire through a web-service to our database.
// Interface:
public interface IHolder<T>
{
void objDetail(List<T> obj);
}
So my initial thought was an interface that will allow me to Generically handle each one of my objects.
// User Interface:
public class UI : IHolder
{
void objDetail(List<object> obj)
{
// Create an Instance
List<object> l = new List<object>();
// Add UI Fields:
l.Add(Guid.NewGuid());
l.Add(txtFirst.Text);
l.Add(txtLast.Text);
// l to our obj
obj = l;
return;
}
}
Now I have an interface; which has been used by our UI to put information in. Now; this is where the root of my curiosity has been thrown into the mixture.
// Create an Object Class
public class Customer : IHolder
{
// Member Variable:
private Guid _Id;
private String _First;
private String _Last;
public Guid Id
{
get { return _Id; }
set { _Id = value; }
}
public String First
{
get { return _First; }
set { _First = value; }
}
public String Last
{
get { return _Last; }
set { _Last = value; }
}
public virtual objDetail(List<Customer> obj)
{
// Enumerate through List; and assign to Properties.
}
}
Now this is where I thought it would be cool; if I could use Polymorphism to use the same interface; but Override it to do the method differently. So the Interface utilizes a Generic; with the ability to Morph to our given Object Class.
Now our Object Classes; can move toward our Entity interface which will handle basic Crud Operation.
I know this example isn't the best for my intention; as you really don't need to use Polymorphism. But, this is the overall idea / goal...
Interface to Store Presentation Layer UI Field Value
Implement the Properties to a Desired Class
Create a Wrapper Around my Class; which can be Polymorphed.
Morphed to a Generic for Crud Operation
Am I on the right path; is this taboo? Should I not do this? My application needs to hold each instance; but I need the flexibility to adapt very quickly without breaking every single instance in the process. That was how I thought I could solve the issue. Any thoughts? Suggestions? Am I missing a concept here? Or am I over-thinking? Did I miss the boat and implement my idea completely wrong? That is where I'm lost...
After pondering on this scenario a bit, I thought what would provide that flexibility while still ensuring the code is optimized for modification and business. I'm not sure this is the right solution, but it appears to work. Not only does it work, it works nicely. It appears to be fairly robust.
When is this approach useful? Well, when you intend to decouple your User Interface from your Logic. I'll gradually build each aspect so you can see the entire structure.
public interface IObjContainer<T>
{
void container(List<T> object);
}
This particular structure will be important. As it will store all of the desired content into it.
So to start you would create a Form with a series of Fields.
Personal Information
Address Information
Payment Information
Order Information
So as you can see all of these can be separate Database Tables, but belong to a similar Entity Model you are manipulating. This is quite common.
So a Segregation Of Concern will start to show slightly, the fields will be manipulated and passed through an Interface.
public interface IPersonalInformation
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
So essentially the Interface is passing its variable, to the Interface. So you would culminate an interface to handle that entire form or individual interfaces that you wish to call so that they remain reusable.
So now you have a series of Interfaces, or a single once. But it contains all these variables to use. So you would now create a class:
public class CustomerProperties: IPersonalInformation, IOrderInformation
{
// Implement each Interface Property
}
Now you've created a container that will hold all of your values. What is nifty about this container is you can reuse the same values for another class in your application or choose different ones. But it will logically separate the User Interface.
So essentially this is acting similar to a Repository.
Now you can take these values and perform the desired logic. What becomes wonderful now, is after you've performed your logic you pass the object into our Generic List. Then you simply implement that method in another class for your goal and iterate through your list.
The honesty is it appears to work well and decouple nicely. I feel that it was a lot of work to do something similar to a normal Repository and Unit Of Work, this answers the question but weather or not it is ideal for your project I would look into Repository, Unit Of Work, Segregation Of Concern, Inversion Of Control, and Dependency Injection. They may do this same approach cleaner.
Update:
I thought about it after I wrote this up, I noticed you could actually implement those property values into the Generic List structure bypassing a series of interfaces; but that would introduce consistency issues as you'd have to be aware of what data is being passed in each time, in order. It's possible, but may not be ideal.
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. :)
I've built a REST API with the WCF Web API Preview and I wanna build a library with the classes that you pass to this API (Just to make the .Net developers life easier). The should be simple POCO classes without much functionality.
But on the receiver side it would make sense for me to add some functionality to these classes. I have an example below:
[WebInvoke(UriTemplate = "", Method = "POST")]
public Supertext.API.Order Create(Supertext.API.Order apiOrder)
{
And this is an example POCO class:
public class Order
{
public string Service { get; set; }
public string OrderTitle { get; set; }
public string Currency { get; set; }
}
Now, what's a good way to extend this class on the server side?
I guess using a subclass would not work.
Delegates?
Actually have two different versions of the class? One for clients and one for the server?
What do other people do?
The problem with adding extra functionality to this POCO class is you are turning it into a domain object. The nature of this domain object will now be constrained by the fact that, essentially, this class acts as the definition of the interface into the operation. Changing details about this class will potentially break clients.
It is a far cleaner model to keep this class purely as a Data Transfer Object whose single responsibility is aiding the bridging of the wire format to objects and use a mapper such as AutoMapper to map the data from the DTO to a real domain object. The real domain object is fully under your control and you can happily refactor it without threatening a cascading effect to your service consumers
We have a huge application with a lot of classes. We are currently porting this .net application to IPad with Monotouch. We have some problems with the DataContractSerializer and we would like to use Marc Gravell's protobuf-net serializer.
The communication between the client and the server is managed by a WCF Service.
A WCF service is made of one Interface exposed to the client and the server, and one implementation of this interface on the server.
The interface looks like that:
[ServiceContract]
public interface IMyService
{
[OperationContract]
SomeObject MyFunction(SomeObject myObject);
}
The server side implementation looks like that:
[ServiceBehavior(...)]
public class MyService
{
public SomeObject MyFunction(SomeObject myObject)
{
}
}
Our classes looks like that:
[DataContract]
public class MyClass
{
[DataMember]
public int SomeProp {get; set;}
[OnSerialized]
public void OnSerialized(StreamingContext context)
{
}
}
So here are my questions:
What would be the changes to do to my classes, wcf interface and wcf implementation.
How would I replace the default WCF DataContractSerializer to the Protobuf Serializer.
Please note that on monotouch, I only have access to Protobuf and Protobuf.Meta namespaces.
[EDIT]
I found a way to swap the serializer runtime:
Custom WCF DataContractSerializer
The above solution uses the DataContractSerializerOperationBehavior. Does Protobuf-net provides such behavior?
In all honesty, I am unfamiliar with the WCF options available to you in monmotouch; they are very different between regular .NET and Silvelight, for example - and I see no reason to assume that monotouch has the ability to swap serializer at runtime (which "full" .NET does, at least under the MS version). This makes it hard to do the transition silently, as we can't wrestle control from DataContractSerializer.
As such, IMO the simplest option is to seize control of the data manually, and send raw byte[] - ideally with MTOM encoding enabled if monotouch can do that. Then once you have your byte[] the world is your mollusc, as they say.
Re changes to your types... well, MyFunction() is an oddity, in that it doesn't transfer any data, so I'm not sure what you want me to suggest on that one. With MyClass, all it needs is a unique number (unique within the type, not globally) per member, i.e.
[DataContract]
public class MyClass
{
[DataMember(Order=1)] // <==== this provides the 1 as the key
public int SomeProp {get; set;}
// see below re callback
}
You also have a serialization callback; these are fully supported, but it expects to find a familiar pattern - StreamContext is not one that I know of (although it should work with StreamingContext and a few others).
Finally, note that by default protobuf-net executes the constructor, which is different to DataContractSerializer. If you desire, you can suppress this via:
[DataContract(SkipConstructor=true)]
public class MyClass {...}
If I've missed the intent here, let me know.
Note there are also ways of doing all the configuration without changing/adding any attributes if you prefer.