Does anyone have any thoughts as to how to get the two to come together so I can get injection of the IBus on the class file?
I tried downloading the Official Nservicebus.Ninject package but it appears to be constrained to the 2.x line of Ninject via Nuget. I went ahead and downloaded the source to the object builder for Ninject. There's a few issues I'm getting through several trial and error scenarios.
The first was that the IBus is not getting set via property injection. This could be my misunderstanding of how the Objectbuilder is being utilized, but I was under the impression that by setting the public IBus Bus {get; set;} on a class within the assembly that it would be set for me.
I then went down the route of trying something along the lines of:
Configure.Instance.Builder.Build<IBus>()
That yielded the following:
Error activating IBus
More than one matching bindings are available.
Activation path:
1) Request for IBus
Suggestions:
1) Ensure that you have defined a binding for IBus only once.
If I do an explicit request for the UnicastBus instead of IBus I do get one instance, but it will bomb out on the base.Activite with the following:
More than one matching bindings are available.
Activation path:
2) Injection of dependency IBus into property Bus of type TimeoutMessageConverter
1) Request for TimeoutMessageConverter
Suggestions:
1) Ensure that you have defined a binding for IBus only once.
I do not claim to be a ninject master (background is spring.net) as this project was handed to me to see if I could leverage it's existing infrastructure that uses Ninject and get a reference to the Bus to invoke a publish from a dispatcher in the project. Been spinning my wheels on this for the better part of day.
Here's the NServiceBus Module being loaded by Ninject (set up taken from another SO post):
public class NServiceBusModule : NinjectModule
{
public override void Load()
{
this.Bind<IBus>().ToConstant(this.CreateBus()).InSingletonScope();
}
private IBus CreateBus()
{
return Configure.With()
.DefineEndpointName("publishMe")
.NinjectBuilder(this.Kernel)
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.InMemorySubscriptionStorage()
.UnicastBus()
.CreateBus().Start(() =>
Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
}
}
I'm not leveraging any IWantCustomInitialization in the EndpointConfig as I thought this was all I would need to get a reference to the Bus.
I have another idea I can approach where I continue to separate the project out a bit that I believe would work just fine (have the web app --setting up bus in the global.ascx -- directly publish to an endpoint and go from there), but trying to stay within the initial requirements of the project outline.
I can supply more information if need be.
NinjectBuilder adds the IBus binding. You have two options:
Use Rebind in your code
Just call CreateBus() without adding the binding
Related
I want to use AutoMapper 9.0 in a WCF project containing several services that will be hosted in IIS. I've only found one other related SO question but its dealing with a 10 year old version of AutoMapper and is not asking the same question. Its answer is similar to the top hits on Google which suggest using a ServiceBehavior but that doesn't seem applicable when I want multiple services to use the same mapper. The defense rests.
In a web project, you might create a static MapperConfiguration in the Global.asax when the application starts, but WCF doesn't have a Global.asax. It looks like there are a few options for executing initialization code in WCF:
Include an AppInitialize() method in the App_Code folder. This will be dynamically compiled at runtime and people have complained that it can have missing reference issues in IIS so I'm not confident AutoMapper or its dependencies will be found once deployed to IIS.
Create a custom ServiceHost. This seems like it would execute once when the application starts, but also looks like it ignores the web.config configuration, which I don't want.
Use the Configure method per service. This has the same drawback as #2 and also I become concerned with thread safety (as in the ServiceBehavior approach) since two services could try to initialize the MapperConfiguration at once.
I considered just creating a class with a static property that would create a static MapperConfiguration or IMapper instance if it was not already created, but as in #3, I'm worried this may not be thread safe. Maybe if I did something like this?
public static class MapperConfig
{
private static IMapper _modelMapper;
private static readonly object _mapperLocker = new object();
public static IMapper ModelMapper
{
get
{
lock(_mapperLocker)
{
if (_modelMapper == null)
{
var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile1()));
_modelMapper = config.CreateMapper();
}
}
return _modelMapper;
}
}
}
Where two services may call ModelMapper simultaneously. Another downside of this is the first request to any service will have to wait for the mapping to compile, but I'm not sure I can get away from that. I definitely don't want it compiling the mappings per call and would prefer not to even have to do it per service. Can you advise on the thread safety of MapperConfiguration and the best way to use it in IIS-hosted WCF?
Consider we have the following class:
[AutomaticRetry(Attempts = 3)]
public class EmailSender : IEmailSender
{
[ErrorReporting(Attempts = 1)]
public async Task Send()
{
}
}
public interface IEmailSender
{
Task Send();
}
And we enqueue job in this way:
backgroundJobClient.Enqueue<IEmailSender>(s => s.Send());
Just to mention, I use SimpleInjector and it's Hangfire job activator.
First of all Attempts property from AutomaticRetry attribute is not taken into account. When it comes to ErrorReporting custom attribute it is not executed at all.
Seems Hangfire checks defined attributes just on registered type (interface in my case) not the instance type that will be resolved.
In my case IEmailSender is defined in seperate project. I believe one solution would be to keep it together with EmailSender and custom attributes implementation, plus define attributes on interface level but I wouldn't like to do it in this way since my Hangfire jobs are processed in Windows Service and jobs themselves are enqueued by clients (using interfaces) so there is no need for clients to know anything about implementation.
Do you have any idea how I could solve this issue in a good way? Can we somehow configure those filters when creating BackgroundJobServer in Windows Service?
I solved it in this way:
https://gist.github.com/rwasik/80f1dc1b7bbb8b8a9b47192f0dfd4664
If you have any other ideas please let me know.
I am in the process of migrating NServiceBus up to v6 and am at a roadblock in the process of removing reference to IBus.
We build upon a common library for many of our applications (Website, Micro Services etc) and this library has the concept of IEventPublisher which is essentially a Send and Publish interface. This library has no knowledge of NSB.
We can then supply the implementation of this IEventPublisher using DI from the application, this allows the library's message passing to be replaced with another technology very easily.
So what we end up with is an implementation similar to
public class NsbEventPublisher : IEventPublisher
{
IEndpointInstance _instance;
public NsbEventPublisher(IEndpointInstance endpoint)
{
instance = endpoint;
}
public void Send(object message)
{
instance.Send(message, sendOptions);
}
public void Publish(object message)
{
instance.Publish(message, sendOptions);
}
}
This is a simplification of what actually happens but illustrates my problem.
Now when the DI container is asked for an IEventPublisher it knows to return a NsbEventPublisher and it knows to resolve the IEndpointInstance as we bind this in the bootstrapper for the website to the container as a singleton.
All is fine and my site runs perfect.
I am now migrating the micro-services (running in NSB.Host) and the DI container is refusing to resolve IEndpointInstance when resolving the dependencies within a message handler. Reading the docs this is intentional and I should be using IMessageHandlerContext when in a message handler.
https://docs.particular.net/nservicebus/upgrades/5to6/moving-away-from-ibus
The docs even elude to the issue I have in the bottom example around the class MyContextAccessingDependency. The suggestion is to pass the message context through the method which puts a hard dependency on the code running in the context of a message handler.
What I would like to do is have access to a sender/publisher and the DI container can give me the correct implementation. The code does not need any concept of the caller and if it was called from a message handler or from a self hosted application that just wants to publish.
I see that there is two interfaces for communicating with the "Bus" IPipelineContext and IMessageSession which IMessageHandlerContext and IEndpointInstance interfaces extend respectively.
What I am wondering is there some unification of the two interfaces that gets bound by NSB into the container so I can accept an interface that sends/publishes messages. In a handler it is an IMessageHandlerContext and on my self hosted application the IEndPointInstance.
For now I am looking to change my implementation of IEventPublisher depending on application hosting. I was just hoping there might be some discussion about how this approach is modeled without a reliable interface to send/publish irrespective of what initiated the execution of the code path.
A few things to note before I get to the code:
The abstraction over abstraction promise, never works. I have never seen the argument of "I'm going to abstract ESB/Messaging/Database/ORM so that I can swap it in future" work. ever.
When you abstract message sending functionality like that, you'll lose some of the features the library provides. In this case, you can't perform 'Conversations' or use 'Sagas' which would hinder your overall experience, e.g. when using monitoring tools and watching diagrams in ServiceInsight, you won't see the whole picture but only nugets of messages passing through the system.
Now in order to make that work, you need to register IEndpointInstance in your container when your endpoint starts up. Then that interface can be used in your dependency injection e.g. in NsbEventPublisher to send the messages.
Something like this (depending which IoC container you're using, here I assume Autofac):
static async Task AsyncMain()
{
IEndpointInstance endpoint = null;
var builder = new ContainerBuilder();
builder.Register(x => endpoint)
.As<IEndpointInstance>()
.SingleInstance();
//Endpoint configuration goes here...
endpoint = await Endpoint.Start(busConfiguration)
.ConfigureAwait(false);
}
The issues with using IEndpointInstance / IMessageSession are mentioned here.
I have a NServiceBus version 3.3.8 Saga that I am working on migrating from NServiceBus 2.6. After I upgraded it, I have found that a single message in the queue is getting processed twice by the saga. What is most strange about it is that NServiceBus is treating this as two separate Transport Messages because my IMessageModule implementation is getting called twice as well.
The message it is receiving is a message bound to NServiceBus 2.6. Has anyone seen this before? I at first thought it was a dependency injection issue, as we are switching from Unity to Autofac, but that doesn't seem to explain the issue with the MessageModule getting called twice.
I appreciate any help you can provide.
UPDATE
It turns out that the issue was a dependency injection issue that I had inadvertently created. The saga has some additional dependencies that require IBus and the IBus is a property and set via property injection. Using an Autofac module, I tried to simplify the configuration by overriding the AttachToComponentRegistration and injecting properties on all registered items like this:
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) {
registration.Activating += (s, e) => e.Context.InjectProperties(e.Instance);
}
This, however, caused the issue above. To fix it, I removed this override and manually set up property injection via a call to:
builder.RegisterType<Implementation>().As<Interface>().PropertiesAutowired();
This resolved my duplicate processing issue. I am still not sure why it caused the issue, but removing that override did prevent the duplicate message handling.
It turns out that the issue was a dependency injection issue that I had inadvertently created. The saga has some additional dependencies that require IBus and the IBus is a property and set via property injection. Using an Autofac module, I tried to simplify the configuration by overriding the AttachToComponentRegistration and injecting properties on all registered items like this:
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) {
registration.Activating += (s, e) => e.Context.InjectProperties(e.Instance);
}
This, however, caused the issue above. To fix it, I removed this override and manually set up property injection via a call to:
builder.RegisterType<Implementation>().As<Interface>().PropertiesAutowired();
This resolved my duplicate processing issue. I am still not sure why it caused the issue, but removing that override did prevent the duplicate message handling.
I have a plugin that I will instantiate at runtime and I want to pass it a WCF service from the application host. The application host is responsible for creating the connection to the service. The reason for this is that a single service can be used by multiple plugins, but the plugins should only know about its interface since there may be several implementation of IMyPluginServices. For instance, the Run method of the plugin instance would be:
public void Run(IMyPluginServices services)
{
services.DoSomething();
}
The problem I am running into is that I don't know how to create a service of type IMyPluginServices and pass it to the Run function. The service reference generated by VS 2010 doesn't seem to create an object of type IMyPluginServices that I can pass to it. Any help would be greatly appreciated. Thanks.
When you add a service reference in VS 2010 for a service it generates an interface named IMyService which contains methods for each OperationContract in your service. It also generates a concrete class named MyServiceClient, which can be constructed and then used to invoke your service.
Now, the problem that you're running into, I believe, is that MyServiceClient is a subclass of ClientBase<IMyService>, and does not implement the generated IMyService interface (which is a real pain).
To get around this problem I ended up making a new interface:
public interface IMyServiceClient : IMyService, IDisposable, ICommunicationObject
{
}
(Note: IDisposable and ICommunicationObject are only required if you want your module to be able to detect/react to faulted channels and other such things).
I then extend MyServiceClient with a partial class (in the assembly that contains my WCF Service reference):
public partial class MyServiceClient : IMyServiceClient
{
}
Now in my modules I can accept an IMyServiceClient instead of an IMyService, and still execute all of the methods that I need to. The application in control of the modules can still create instances of MyServiceClient as it always did.
The beauty of this is that your new interface and partial class don't need any actual code - the definitions suffice to get the job done.