I'm playing a bit with SignalR and relating it back to some previous Pub/Sub work. In it, we have a Base Event with a couple of mandatory properties and then several Derived Events for specific payloads.
With SignalR, it appears that I need to define a hub based on each of the derived events as Send is going to deal with a specific type. For example, if I create a hub for the base class I can send any of the derived types or the base type without error but I always get back a base type losing any of the derived type's properties.
Seems my choices are a hub for each type or putting the derived properties in some type of blob to be parsed out by the receiver.
How far off is my thinking?
AFAIK, SignalR is based on a dynamic way to describe and (de)serialize payloads, so its runtime tries to match the type specified on the receiving part, without trying to further match any derived type. It's a mechanism which has the advantage of being able to work without requiring to share types across clients and server, but the disadvantage you are experiencing. This should explain what you see.
You could base your solution on the usage of dynamic, if you want to keep your hierarchy of payloads you'll have to take care yourself of deserialize the received dynamic value into instances of those, maybe with the help of a "record type" member on the base class. You would not need to do a full parsing.
Related
This issue comes up for me so often in my coding that I'm astonished I can find so little reference to it, and would value other people's thoughts and ideas.
I define lots of APIs, for the frameworks I work on, and within large domain models that I want to break up. Those APIs consist almost entirely of interfaces (meaning, in my case, C# interfaces). I find, over and over again, that I want to distinguish between two kinds of interface. In the absence of finding any more widely used terms, I define these two as follows:
'Role' interfaces are intended to be implemented by objects outside of the API, in order that those objects can be used as arguments for methods defined on the API.
'Result' interfaces are implemented by objects inside the API and made available to other parts of the system via the API. The intent of defining a result interface rather than exposing the object that implements it is to restrict the view of the object to the outside world.
To pick one example, a Payments sub-system might define IPayableItem as a Role interface, implemented by many types in other parts of the application in order that Payments may be generated for them. Those generated Payment objects may be retrieved via the API but defined by the Result interface IPayment.
The only way I can currently distinguish these is by naming convention and/or commenting. Ideally, I would like the distinction enforced by the language, and have it enforce the rule: you can't implement a Result interface outside the API, only use it. But C# doesn't provide any such mechanism. (Can anyone advise me of a language that does?). I could define an attribute, but this still wouldn't enforce anything.
Another important significance of the distinction lies in Semantic Versioning of the API. If I add a new member to a Role interface then this should be seen as a breaking change (and hence a first-level version) - because any existing external implementations will need to add that member. But if I add a member to what I deem to be a 'Result' interface then it should only be my own code that is impacted - it is just a new feature (second-level version) for everyone else. But with no enforced distinction between the two types there's some risk that people are implementing the Result interfaces and hence their code would be broken.
Has anyone else encountered this dilemma? If so, how have you dealt with it? I look forward to your answers.
But please don't both to respond with either of the following arguments (which I have heard all too often):
My Result interfaces should be abstract classes rather than interfaces. This does not solve the problem, and potentially makes it worse, since external code can sub-class them.
I should be returning the concrete type and ensuring that anything I don't want accessible outside the API is marked 'internal'. There are lots of cases where I need things inside the API to be public, e.g. to be accessible to other frameworks (not going through the API).
I think what you're asking is it possible to expose an interface, but determine that a given instance is one you created?
If so, you could also create an internal private interface, and mark all your implementations as also implementing the private interface. Then upon being given an object from the outside world, verify it has the internal interface implementation as well.
public interface IPublic
{
...
}
internal interface ISecret { }
public class PublicImplementation : IPublic, ISecret
{
...
}
Only you can implement the ISecret, so even if someone implements the IPublic and passes it to you, it will fail the ISecret test.
Is there any way to glue metadata to an object in C#?
Context: Framework which is sending messages between peers over the network. Messages can be arbitrary serializable user-defined .NET types.
Of course, when a message is sent by a peer, the framework could wrap the object into a Message class which saves the metadata, and the receiver could unwrap it. However, the processing method of the peer could decide to resend the message to another peer - however, I want to keep the original metadata. The user should not be required to use Message.RealMessage all the time except when resending it.
I thought about keeping the wrapped instance in a dictionary and upon resending looking up if there is already a wrapped instance in the dictionary and resending that one, however, as messages may not be resent at all (or resent multiple times) this would require more and more memory.
Any solutions? Maybe C# directly supports gluing additional information to an object? Normally I would go for an internal interface, however, the user would have to derive all its classes from a framework's base class, which is not possible.
Edit: I kind of want to say "here is an object of WrappedMessage but you are only allowed to use the interface provided by the class T".
There is the ConditionalWeakTable that should do what you want a little better than using directly a Dictionary.
To quote:
Enables compilers to dynamically attach object fields to managed objects.
You can ignore the part about the class being for compiler :-)
To lay out the problem as easily as possible, I'm trying to implement a generic pooling system that can handle an arbitrary number of concrete classes so long as they implement IBaseComponent.
So, in my class that manages the pools, I have a Dictionary of Pools:
Dictionary<Type, Pool<IBaseComponent>> pools;
As this will allow me to create as many classes that implement IBaseComponent (which is a very 'low level' interface, so to speak - so classes implementing it are not going to be compatible too terribly far) as I want, and there can be a pool for each.
Now, the issue I'm running in to is the first load of an IBaseComponent into the pool, to act as a template, so to speak.
This template object is loaded from XML, rather than code, so I do not have its actual class at compile-time, only at run time (it's defined in the XML definition and I grab the formal Type via reflection). That's all fine and dandy except, as we know, generics rely on compile-time safety.
So, using some reflection trickery I have the following:
var type = typeof(MyChildComponent);
var genericType = typeof(Pool<>);
var specificType = genericType.MakeGenericType(type);
var pool = Activator.CreateInstance(specificType );
pools.Add(T, pool as Pool<IBaseComponent>);
assuming some class:
public class MyChildComponent : IBaseComponent
The problem occurs at the last line in the first block there, when I'm adding to the pools dictionary. The cast of the instantiated pool to Pool<IBaseComponent> fails, resulting in null being inserted into the Dictionary.
My question to you fine folks is this: Is there any reasonable way around this? Any possible way, even?
If I need to load elements via some external method (XML, TXT, whatever) for at least the very first template object for a pool, for each possible concrete class that a Pool could be used for, and all I have access to is the top-level interface and formal Type of the class (both defined in the external definition file), can I do anything here?
Or is this simply not possible at all?
Are you using .Net 4+? If so, you can create an interface IPool<out T>. The out makes the generic argument covariant, which means it will accept any version of the interface with a generic argument which is T or derives from T.
For some reason co/contravariance only works with interfaces and delegates, which is why you need IPool.
Your Dictionary will become:
Dictionary<Type, IPool<IBaseComponent>>() pools;
I'm having a little trouble combining it in my head with the reflection, but I think that should work. If not, let me know and I'll spend a little more time on my test code.
One alternative option I'm toying with is modifying Pool<T> itself.
Instead of having Pool<T> store only one type of (concerete) class, I will modify it to support storing any compatible class based on an interface used for T.
So, Pool<IBaseComponent> will be responsible for storing all possible types that implement IBaseComponent.
Internally, it will store everything as an IBaseComponent, but will keep references to where each concrete type is stored (in a Dictionary of lists keyed by Type, perhaps, or even just one big linear list [although this would make resizing the "pool" for specific types a lot more complicated])
One thing I neglected to mention is that IBaseComponent exposes two points of functionality that are all I need for preparing a component for use in a "blind" fashion (ie: the factory that would be calling this pool doesn't know at compile time what types of components it's working with either, it just loads them up based on what's defined in XML, or copying from an existing object that has these components attached to it), namely: Deserialize (build component from XML/JSON/whatever) and CopyInto(IBaseComponent other) (build component by copying from another component).
So, this would still have the problem that the Pool won't be able to dynamically cast the IBaseComponent to the caller's requested Type, but that won't matter. If the caller really knows the hard compile-time type ahead of time it can do the cast. If the caller doesn't, then it wouldn't be able to do anything beyond access methods exposed by IBaseComponent anyways.
All that matters is that the IBaseComponent the Pool returns is of the correct type underneath, which this will handle.
Put simply: I'll be cutting out a bit of modern generics (interally the Pool will only work with passed-in Types, externally it will only allow T to be an interface), and replacing it will good ol' fashioned Type passing. Reflection will have to be used internally to instantiate the Pool of Types, but I figure that it's okay to expect that initializing or resizing a Pool is going to be a very costly manouever.
My client-server communication looks like this: there are some so called annoucements which are seperate messages used to exchange information. The idea is that annoucement is the common part of every message. Actually I suppose it will be the type of the message. The type decide what is the content. In UML class diagram Annoucement would be the class all other messages inherit.
I want to implement that idea in communication between two applications one written in C++ the other in C#. I thought I could write a message that contain one field with the type if the message (an enum field) . All additional information relevant to the type would be implemented as an extensions.
I have found some examples how to use extensions in C++, however I have no clue how to do it in C#. I know there are interfaces IExtensible and IExtension (in protobuf-net) but how can I use them? Internet resources seem to be poor in the matter.
I suppose in the past messages in C# used to be define similiar to fashion that they are still defined in C++ apps (using proto file and protoc). Can I use the same proto file to define the message in C#? How? Will extenions be interpreted or overriden?
If I could implement extensions, I would sent a message, parse it, check the type and use approriate function to maintain it. That sounds to me cool because I wouldn't have to take care of the type of the message I was going to read - I don't have to know the type before parsing.
There are a number of ways you could do this. I'm not actually sure extensions is the one I would leap for, but:
in your message type, you could have a set of fully defined fields for each sub-message, i.e.
base-message
{1-5} common fields
{optional 20} sub-message 1
{optional 21} sub-message 2
{optional 22} sub-message 3
{optional 23} sub-message 4
sub-message 1
{1-n} specific fields
where you would have exactly one of the sub-message object
alternatively, encapsulate the common parts inside the more specific message:
common field type
{1-n} fields
sub-message 1
{1} common field type
{2-m} specific fields
Either approach would allow you to deserialize; the second is trickier, IMO, since it requires you to know the type ahead of time. The only convenient way to do that is to prefix each with a different identifier. Personally I prefer the first. This does not, however, require extensions - since we know everything ahead of time. As it happens, the first is also how protobuf-net implements inheritance, so you could do that with type inheritance (4 concrete sub-types of an abstract base message type)and [ProtoInclude(...)]
Re extension data; protobuf-net does support that, however as mentioned in the blog this is not included in the current v2 beta. It will be there soon, but I had to put a line somewhere. It is included in the v1 (r282) download though
Note that protobuf-net is just one of several C#/.NET implementations. The wire format is the same, but you might also want to consider the directly ported version. If I had to summarise the difference I would say "protobuf-net is a .NET serializer that happens to be protobuf; protobuf-csharp-port is a protobuf serializer that happens to be .NET" - they both achieve the same end, but protobuf-net focuses on being idiomatic to C#/.NET where-as the port focuses more on having the same API. Either should work here of course.
I'm having a problem in that I'm using an LdapConnection to make requests against an AD LDS (formerly known as ADAM) datastore. Fine. But now requirements have come along to be able to "remotely" do this. Basically, a program we could count on always having access to the datastore now needs to do it through a "server" program on the "internal" network, so that the "client" on the external one only communicates through our new "server" program. There's a reason (not a great one, but a reason) why we can't just expose the AD LDS server to the outside. But they want it done "fast" and thus don't want to re-engineer the client app (as should be what's really happening). Thus we need to serialize the DataRequest and DataResponses to go to and from the "server" part.
Big problem: The DataResponses don't seem to be serializable. During testing, a DataContractSerializer has no problem serializing my SearchRequest but the SearchResponse gets this:
System.Runtime.Serialization.InvalidDataContractException occurred
Message="Type 'System.DirectoryServices.Protocols.SearchResponse' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types."
Source="System.Runtime.Serialization"
StackTrace:
at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)
InnerException:
OK. But neither type has Serializable or what not. So why does SearchRequest go through the process fine, and the response doesn't?
But that doesn't even matter in the end. How am I supposed to serialize a type that I can't change, as it's built-in to the .NET framework, and I can't "re-make" because the constructor is internal? If I could just "take the information I needed" and re-make the class on the other end of my network connection, I would, but these types don't have public constructors.
Any ideas? I'd even like to know why one of the types "just works" even without the right attributes for the DataContractSerializer but the other doesn't.
The best - and probably only - approach is to create your own wrapper class and then read the result and store in the class and serialise.
SearchResponse in fact is a COM wrapper and cannot be serialised.