I recently moved to using the binary serializer to send messages with NServiceBus. My messages are all defined as interfaces and are instantiated using
bus.Send<MessageType>(msg => msg.Property = someValue)
This leads to an exception being thrown from NServiceBus stating that
Cannot create an instance of an
interface
I can see from the stack trace that the SimpleMessageMapper is being used, and after looking in the source can see it's making a call to Activator.CreateInstance.
I can't find anything in the documentation stating that it's not possible to do what I'm trying to do, is there a way to fix this?
Thanks,
Matt
I only just started playing with nServiceBus, so all I can offer you is theory :).
Are you defining the implementation classes for your message interfaces, or is nServiceBus generating classes on its own? If the former, make sure you still have a default constructor and that the class and all fields/events are marked as [Serializable] or [NonSerialized]. If the latter, it's possible that nServiceBus doesn't know how to generate members which may be needed for (de)serialization. You may have to write and map the implementation class yourself.
Related
I have two different Java 8 projects that will live on different servers and which will both use Akka (specifically Akka Remoting) to talk to each other.
For instance, one app might send a Fizzbuzz message to the other app:
public class Fizzbuzz {
private int foo;
private String bar;
// Getters, setters & ctor omitted for brevity
}
I've never used Akka Remoting before. I assume I need to create a 3rd project, a library/jar for holding the shared messages (such as Fizzbuzz and others) and then pull that library in to both projects as a dependency.
Is it that simple? Are there any serialization (or other Akka and/or networking) considerations that affect the design of these "shared" messages? Thanks in advance!
Shared library is a way to go for sure, except there are indeed serialization concerns:
Akka-remoting docs:
When using remoting for actors you must ensure that the props and messages used for those actors are serializable. Failing to do so will cause the system to behave in an unintended way.
For more information please see Serialization.
Basically, you'll need to provide and configure the serialization for actor props and messages sent (including all the nested classes of course). If I'm not mistaking default settings will get you up and running without any configuration on your side, provided that everything you send over the wire is java-serializable.
However, default config uses default Java serialization, which is known to be quite inefficient - so you might want to switch to protobuf, kryo, or maybe even json. In that case, it would make sense to provide the serialization implementation and bindings as a shared library - either a dedicated one or a part of the "shared models" one that you mentioned in the question - depends if you want to reuse it elsewhere and mind/don't mind having serailization-related transitive dependencies popping all over the place.
Finally, if you allow some personal opinion, I would suggest trying protobuf first - it's binary format (read: efficient) and is widely supported (there are bindings for other languages). Kryo works well too (I have a few closed-source akka-cluster apps with kryo serialization in production), but has a few quirks with regards to collection/map handling.
I wonder if it's possible to get an instance of the JAX-RS Application a resource is attached on. Ideally a way that isn't dependent to a specific implementation. For example using dependency injection...
Thanks very much for your help,
Thierry
As stated in The Spec
5.2.1 Application
The instance of the application-supplied Application subclass can be injected into a class field or method parameter using the #Context annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.
but from I've experienced, it will most likely not be the actual instance, but a proxy. Also if you're looking to alter anything on it, I'm not sure it's possible. It might be read-only.
I'm engaged in building NServiceBus Gateway handler, and I need to avoid config files so that all configuration is defined inside c# classes. As a result I have to convert the following section to c# code
<GatewayConfig>
<Channels>
<Channel Address="http://localhost:25899/SiteB/" ChannelType="Http" Default="true"/>
</Channels>
</GatewayConfig>
I've found GatewayConfig, ChannelCollection and ChannelConfig in a NServiceBus.Config namespace, but I can not link them together, coz GatewayConfig refers to ChannelCollection, but ChannelCollection has nothing to do with ChannelConfig. Please help
Just create a class implementing IProvideConfiguration of GatewayConfig. That gives you a way to provide your own config. Look at the pubsub sample for the exact details on how to do this.
Well, I've found the way to do it as I installed Reflector and looked into the implementation. There is a ChannelCollection.CreateNewElement() method returning back System.Configuration.ConfigurationElement. NServiceBus overriden the method instantiating ChannelConfig inside it, so all I have to do is to cast ConfigurationElement type to ChannelConfig type which is far from intuitive interface. Looks like this NServiceBus.Config.ChannelCollection is kind of unfinished work, because if you look at other collections like NServiceBus.Config.MessageEndpointMappingCollection you can find there all necessary type-safe methods to work with its child elements NServiceBus.Config.MessageEndpointMapping, so I think NServiceBus team was just lazy to make the same for ChannelCollection.
UPDATE: as CreateNewElement() method is protected, I have to implement my own class inherited from ChannelCollection to make a method adding new ChannelConfig element publicly available
I developed my code based on this posting :
Asynchronous Programming Model in WCF with async/await
There was no compilation error but when hosted it generates below specified error :
Type 'System.Threading.Tasks.Task`1[System.String]' cannot be serialized. Consid
er marking it with the DataContractAttribute attribute, and marking all of its m
embers you want serialized with the DataMemberAttribute attribute. If the type
is a collection, consider marking it with the CollectionDataContractAttribute.
See the Microsoft .NET Framework documentation for other supported types.
What could be the reason for this.
It looks like one of your methods is either returning a Task object, or has a Task object as one of its parameters.
Tasks cannot be passed across the web-service boundary - this is the cause of your problem.
Update: I had a look at the link you got this code from, and it looks like the code provided is conceptual only. If you look closely at the wording, he says 'will' instead of 'can'.
WCF vNext will adopt the Async model
in both the client and the server
side, and provide new Task-based
overloads for some of the most used
asynchronous APIs.
Since a Task cannot be passed over the web-service boundary, it will not work.
A little question regarding Ninject.
I use a WCF 'duplex channel' to communicate with a service. The channel is defined as an interface, lets call it IMyChannel for simplicity. To instantiate a channel we use DuplexChannelFactory<IMyChannel> object's CreateChannel() method.
So far I have manage to bind the factory class with this.
Bind< DuplexChannelFactory< IMyChannel>>().ToMethod(context =>
new DuplexChannelFactory< IMyChannel>(
new MessageEndPoint(),
new NetTcpBinding(),
"net.tcp://localhost:8321")).InSingletonScope();
}
}
However I'm a little unsure how to bind the IMyChannel interface since I use Ninject to create DuplexChannelFactory<IMyChannel> so to bind IMyChannel I do Bind< IMyChannel>(). ???
This isnt really an IOC container issue.
While, in theory, you could do:
Bind<Func<IMyInterface>>().ToConstant( context => context.Kernel.Get<DCF<IMC>>().CreateChannel)
and then demand a Func<IMyInterface>() in your ctor, calling it whenever you want to create a channel.
The problem is that the object that CreateChannel() returns implements both IMyChannel and IDisposable, hence you cannot neatly use a using block around it if that's what you're going to return. This is what the tooling generates for you when you create Service Reference, and WCF OOTB doesnt offer a general mechanism here.
I personally inject a factory, and have it have a Create<T>() method that yields a wrapper object that:
implements IDisposable
has a way to call methods across the channel.
It's not injectable into a post so hopefully someone will be along soon with a nice wrapper class of this nature.
Not sure if Singleton is appropriate, but I'd have to look around to be sure.