Inheritance in datacontracts - c#

I have a class say supplierAddress which comes from a webservice (it is a datacontact). I then have a second class myAddress which inherits from that class and has a few more constructors and metods.
What I want to do is pass a myAddress back to the webservice. When I pass a cast down myAddress it throws seriazation errors, which makes sence as its a refrence object and the whole object is still being passed even if im casting down.
Is it possible to clone just the base class of an object? Is what im trying to do possible/correct ?

You should specify Known types for your base class.
UPDATE: additional clarification.
SOA (Service-Oriented Architecture) paradigm doesn't support such common features like polymorphism or method overloading. This behaviour based on very simple fact: you don't know which platform will consume your service. Its definitely possible to consume your service in platform or language that doesn't support such thing like inheritance or method overloading.
That's why you should create your service functions with unique names and that's why you should explicitly stated what types you're going to pass instead of base class reference.
When you specify known types this information would expose out of your service through metadata and every client could understand how to deal with your responses.

Related

How to expose "generic" C# collection to COM

I have an API which I have developed a C# client for which converts HTTP GET requests into C# objects.
I have made the client COM visible as I need it in VB6, the issue here is that generic collections does not work over COM. I have made a "fix" for this by making my own implementation of a collection except it is not generic.
This means I have a class named [Class]_Collection for each of my classes, this just means I have a collection without the generic class.
This works well except our API is quite large with quite a few different objects, so it would be nice if I did not have to write the implementation for every class in our API.
I have been experiementing with a generic base class or generic interface which I can inherit, but as previously stated COM does not like generic classes.
I also require an IDispatch interface to expose functionality so that the class functions are exposed in VB6.
Is there a way in which I can write the implementation for all my collections and just inherit that functionality everywhere it is needed?
Generics are indeed incompatible with COM, as far as I know there is no way around that restriction in itself.
The approach I've used as a simple workaround is to add wrapper properties specifically for COM-interop purposes.
Example:
[ComVisible(false)]
public List<int> SomeNumbers {get; set;}
[ComVisible(true)]
[Obsolete("Use this for COM interop only")]
public IList SomeNumbersCOM => SomeNumbers;
This has the benefit of being fairly simple, does not actually copy any data, and functions through COM. However it is obviously not typesafe since within VB6 the entries of SomeNumbersCOM will just appear to be object. But VB6 isn't especially typesafe anyway, so this may not really be a big problem. And at least the real strongly typed collection can be used within C#. The Obsolete helps to enforce this.
The mild loss of type safety hasn't been a real issue in my experience. You still can assert the correct type on the VB side; e.g., use a Long variable when getting values out of the SomeNumbersCOM list..
You don't have to add very much code that isn't just boilerplate. e.g., you don't have to actually code collection classes or replicate their internal logic.
Instead of wrapping properties in the same class, you could create an entire wrapper class, which would be a bit cleaner for the C# consumers.
Creating an entirely separate COM-visibility wrapper assembly (which contains all those wrapper classes) would be an even stronger way to mandate that the wrappers are NOT used from elsewhere on the C# side.

What is the difference between an Interface and a concrete instance from the compiler / CLR point of view?

I understand that an interface is an abstract type that contains no data, but exposes behaviours and properties, and that an instance of an object is an occurrence or a copy of an object that exists in memory.
I'm wondering about the differences in how the compiler / underlying code deals with the two? Based on the answer to this, why is the code more loosely coupled if I pass an interface as a dependency to an object rather than a concrete instance? What is the difference between what happens if I call the DoSomething method defined in an Interface to MyClass rather than the DoSomething method defined in the concrete instance of MyClass?
I know you said you understood what an interface is - but I do wonder if that's entirely true given the way that you've linked your second question with the first. The second can be answered without any knowledge of the first, nor is it influenced in any way by it.
Specifically on the question of why it's more loosely coupled has nothing to do with the implementation of the compiler or anything: it's just software architecture.
Interfaces impose no restrictions on the implementing type other than the presence of the method/property (well, technically they're methods too).
The implementation doesn't even have to be public on the type itself, nor does the type have to have a certain constructor etc. More importantly - it doesn't even have to be a class. Then there's the (rather edge-case) thing that with interfaces a single type can have multiple implementations of the same interface.
As soon as you use a base class potentially introduce a whole load of other restrictions.
True, these can clearly be a good thing too - for example if a known concrete base is known to be immutable (for consistency) and which doesn't allow 'nulls' in it's constructor etc (all not enforcable through an interface).
You can have many implementations (concrete instances) of an interface or abstract class.
In general you should define methods that accept the class hierarchy with the interface and not the concrete classes, so that they will be generic and wont have to be rewritten for each new implementation you define.
Calling the method on the base class or in the derived class should call the same method, assuming you correctly override the method.
Have a look at the MSDN magazine article: "Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects" for implementation details.
I think the main reason why the runtime needs to support interfaces is especially related to the fact that assemblies with different compile times might connect to each other at runtime.

Adding AutoMapper Type Mapping Conventions For Generic Types in WCF Contract

I have a WCF service that uses generics in its data contract, for example (simplified):
public GetDetails(StatusField<string> status);
Now WCF supports generics by creating a non-generic equivalent type for every possible value of T in the generic. So, for the above example, the client consuming the WCF service will see the following signature for the above function:
public GetDetails(stringStatusField status);
//...
Now the client has a copy of the generic version of the StatusField class. We want to use AutoMapper in the client, to map between this generic StatusField and the types generated above by WCF (such as stringStatusField) so we can call the service. We could do this by manually creating the maps at client startup, like so:
Mapper.CreateMap<StatusField<string>, stringStatusField>();
However this is laborious as there are 50+ possible values of that WCF has converted. Extending this idea, we could use reflection to automatically create maps for all the types and this is the solution we are currently using.
Ideally what i would like to see is a solution that ties into the architecture of AutoMapper to avoid having to do the reflection manually. conceptually, this would require some way of defining a convention that AutoMapper would use to allow it to tie the two types together, similar to how it allows custom conventions to be specified when matching properties. As yet, i have not seen a way to do this and this is the question i would like answered here, if anyone knows how this can be done, specifically in relation to the above scenario.
BTW i am aware that some may be thinking of Mapper.DynamicMap() as a solution to this problem. Firstly, we dont want to use this as it means debugging could potentially be harder (as indicated by some in other posts similar to this) and also if the StatusField is deeply nested in an object graph being passed to the WCF method, im not sure this solution would work and could potentially lead to a type being incorrectly mapped and other such issues. I would really like to concretely define the allowable mappings if possible.
Unsure if AutoMapper provides the support you are after, but if it did it would be using reflection as you propose.
If you are opposed to the reflection solution due to performance concerns (which should be a one-time startup cost), then maybe a T4 template-based code generation solution might be worth considering?

extending a class that doesn't implement an interface

I'd like to override the Serialize methods of the ASP.NET JavaScriptSerializer class. Nothing too fancy, I just want to do some additional post processing to the serialized string returned from .NET.
Unfortunately, none of the methods on this class are declared virtual and the class itself does not derive from an interface or abstract class (seems like a strange oversight given how many of the core .NET Framework classes are designed for extensibility).
Based on some reading I've done on the subject, it appears that I have a couple of options to choose from.
Create an extension method. I'm not a huge fan of this option, since it involves creating a new method (compiler won't allow using the same name/signature twice) that class consumers would need to be aware of.
Derive a new class from JavaScriptSerializer that has the exact same signature. Since JavaScriptSerializer has no virtual methods, I would use the "new" keyword in each method/property declaration in order to perform method hiding. I think this option is considered a decorator pattern?
Create a new interface called IJavaScriptSerializer that would have the same signature as JavaScriptSerializer. Remove all references in my code to JavaScriptSerializer and replace with references to the newly created interface.
I'd love to hear about additional approaches and the pros/cons of each approach.
Thanks for taking the time to read.
You're misunderstanding the Decorator Pattern, which refers to an object that inherits a class and wraps another instance of that class. (This is very common for streams). In your case, it's inapplicable.
I would recommend that you make your own replacement (or wrapper, whichever you need) for the JavaScriptSerializer class, without trying to have an identical API. If you need to be able to swap implementations, I would make an interface or base class with the core methods, and have two concrete implementations of it, one wrapping the original and one adding your post-processing.
In general, when designing classes, you should design to meet your needs, not to copy the .Net Framework's built-in classes.
Go to http://json.org and d/l one of the several classes that have source code, for JSON serialization.
Then, put in your post-processing, compile and use in your project.
Ideally, at this point I would create an extension method so I can just do this:
List<MyObject> s = fillObject();
return s.ToJSON();

Using an interface in a C# xml web service

How can I use an interface (from which classes implement) in an XML web service?
When I do so, I get a YSOD claiming the interface is not serializable. If I add the Serializable attribute to the interface's class, there's another error which hampers progress (can't remember which).
For the most part interfaces are not serializable without some work. Usually this error is encountered when the class being serialized contains an object that is using an interface as a variable, or some variation of this. For instance, a property like this would throw an error:
[Serializable]
public class TestClass
{
private ICustomInterface _iCustomInterfaceObject;
public ICustomInterface CustomInterfaceProperty
{
get { return _iCustomInterfaceObject; }
set { _iCustomInterfaceObject = value; }
}
}
For the sake of the argument (and not making me type additional validation code), let's say that you always are assigning CustomInterfaceProperty to an object that inherits from ICustomInterface (as is required when using interface types like this). Even if it is 100% sure to always be populated, it won't allow you to serialize the TestClass.
To get around this, you need to make sure the interface you are using, the one that is throwing the error, also inherits from ISerializable. That way you are promising that all of the objects inheriting from ICustomInterface also have serialization methods implemented.
Unfortunately, this is not the case when using xml serialization. If you are using the serializers found in System.Xml.Serialization then this method won't work, since, as Robert Harvey pointed out, an interface does not contain a parameterless constructor (which is required when using the xml serializers). My suggestion for now, if you are set on this method of serialization, attach the attribute [XmlIgnore] to the section in question and move on from there.
My advice is to treat the objects that go over the wire as basic data transfer objects and nothing more. You're tempted to just use your domain objects and serialize them, but as you're already seeing, normal in-memory objects can have far more complexity than can be serialized without a lot of work, and sometimes not at all.
You can also end up limiting functionality of your domain classes just to keep them serializable.
Finally, a more subtle bug to avoid, and a reason to have separate DTO's, is that you otherwise are tightly coupling your domain objects to a publicly published interface i.e. the web service itself. Versioning a web service can be a hassle, and it's easier if your service interface isn't tightly coupled to your domain classes.
I'm guessing that the other message is that you can't serialize the interface because it doesn't contain a default (parameterless) constructor.
If the underlying classes are framework classes, you might be hosed. Some of them are not marked serializable, and some of them do not have parameterless constructors.
Also, you may be getting confused between runtime serialization and XML serialization. XML Serialization is what the old ASMX web services use. It does not pay much attention to the [Serializable] attribute, but mostly just serializes the public read/write properties of public classes which have a default constructor.

Categories

Resources