AutoFac Exception after upgrading NServiceBus - nservicebus

I just upgraded NServiceBus from 4.6 to 5.0
I did the steps suggested in the "4 to 5" document and am able to compile. Now I receive the following Error:
None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'Nop.Web.Controllers.ShoppingCartController' can be invoked with the
available services and parameters: Cannot resolve parameter
'NServiceBus.IBus bus' of constructor 'Void .ctor(NServiceBus.IBus, ...
What has to be done?
(Update: My Configuration)
public static class ServiceBus
{
public static void Init(ILifetimeScope scope)
{
var configuration = new BusConfiguration();
configuration.EndpointName(ConfigurationManager.AppSettings["ServiceBusEndpointName"]);
configuration.UseTransport<MsmqTransport>();
configuration.UseSerialization<JsonSerializer>();
configuration.UsePersistence<RavenDBPersistence>();
configuration.DisableFeature<Sagas>();
configuration.Transactions().Enable();
configuration.AssembliesToScan(AllAssemblies
.Matching("Nop.Services.dll")
.And("TengoMessages.dll")
.And("Partner.Pricing.Messages.dll")
.And("Partner.Pricing.Infrastructure.dll"));
configuration.UseContainer<AutofacBuilder>();
configuration.PurgeOnStartup(false);
var bus = Bus.Create(configuration);
bus.Start();
var newBuilder = new ContainerBuilder();
newBuilder.RegisterInstance(bus);
newBuilder.Update(Singleton<IContainer>.Instance);
}

I don't use AutoFac, so I'm not familiar with the ContainerBuilder concept, but it looks like you want to use an existing container with NServiceBus?
Create the instance of your container first, and then change your configuration code to use:
configuration.UseContainer<AutofacBuilder>(customizations =>
customizations.ExistingContainer(container));
It looks like the second to last line of code is registering the bus--this should not be necessary, as the above code will ensure all NSB-related classes get properly registered.

Related

Strongly typed configuration is not registered but still retrieved from ServiceProvider

I wrote a test that checks that every ...Configuration class in my project (I have several of them) is resolved when I call serviceProvider.GetRequiredService. The test works, but I don't understand why it works also when I remove the registration for a class: I just need to register a single configuration. For example:
[Fact]
public void Test()
{
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("./Configurations/appsettings1.json");
var services = new ServiceCollection();
//services.Configure<ActorSystemConfiguration>(configuration.GetSection("ActorSystem"));
var serviceProvider = services.BuildServiceProvider();
var configurationSection = serviceProvider.GetRequiredService<IOptionsMonitor<ElasticSearchConfiguration>>();
Assert.Equal("elasticsearchserverurl", configurationSection.CurrentValue.ServerUrl);
}
if I run the test in this way, without any call to services.Configure, then I get the expected behaviour with a "No service for type 'Microsoft.Extensions.Options.IOptionsMonitor`1[TNW.Server.Configurations.ElasticSearchConfiguration]' has been registered." exception.
If I remove the comment on the line about services.Configure (note: about another configuration section!) then I always get an empty but not null configuration object.
From the documentation GetRequiredService should throw the exception and GetService should return a null object.
I want to understand what is going on in order to be sure that I am not doing anything wrong and eventually I don't need to care about missing registrations here.

Ninject Moqing Kernel (what does reset do?)

I have an interface that I'm using with a couple different concrete classes. What I wish is that there was something like this...
_kernel.GetMock<ISerializeToFile>().Named("MyRegisteredName")
.Setup(x => x.Read<ObservableCollection<PointCtTestDataInput>>(
It.IsAny<string>()));
The project I'm working on uses the service locator pattern - anti-pattern which I'm getting less fond of all the time...
Originally I tried..
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_kernel = new MoqMockingKernel();
}
[TestInitialize]
public void TestInitialize()
{
_kernel.Reset();
ServiceLocator.SetLocatorProvider(
() => new NinjectServiceLocator(_kernel));
_kernel.Bind<ISerializeToFile>().ToMock()
.InSingletonScope().Named("ObjectToFile");
_kernel.GetMock<ISerializeToFile>()
.Setup(x => x.Read<ObservableCollection<PointCtTestDataInput>>(
It.IsAny<string>()));
_kernel.GetMock<ISerializeToFile>()
.Setup(x => x.Save<ObservableCollection<PointCtTestDataInput>>(
It.IsAny<ObservableCollection<PointCtTestDataInput>>(),
It.IsAny<string>()));
}
I got the standard Ninject error stating that more than one matching binding is available. So, I moved _kernel = new MoqMockingKernel(); into the TestInitialize, and then that error went away... Perhaps I'm incorrectly guess at what _kernel.Reset() does?
Reset removes any instance from the cache. It does not delete existing bindings. So the second test will have the ISerializeToFile twice.

How to implement an async wcf client for a synchronous service

Is there a way to create an async client for a synchronous WCF service without adding a service reference? This is for a .NET 4 client.
A service reference in Visual Studio is nothing else than a code generator that creates a proxy class with corresponding data elements necessary to call your web service. Of course you can hand build a proxy if you really want to go over tedious and boring work.
Maybe start by decompiling System.ServiceModel.ClientBase using .net reflector?
Do some research on ChannelFactory: http://msdn.microsoft.com/en-us/library/system.servicemodel.channelfactory.aspx
Even when implementing my own client by wrapping a ChannelFactory, I am still using the Add Service reference in another project to create the class definitions and move them into the real project. That's a good compromise.
Here's a simple async service interface:
[ServiceContract(Name = "IService")]
public interface IServiceAsync
{
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetStuff(string someData, AsyncCallback callback, object state);
IEnumerable<Stuff> EndGetStuff(IAsyncResult result);
}
The .NET contract might look like this:
[ServiceContract]
public interface IService
{
[OperationContract]
IEnumerable<Stuff> GetStuff(string someData);
}
Then in code, assuming you use HTTP, No security and binary message encoding, something like this (Sorry I haven't compiled any of this, just typed it using some of the code I have written for projects):
//Create a binding for the proxy to use
HttpTransportBindingElement httpTransportBindingElement;
httpTransportBindingElement = new HttpTransportBindingElement();
absoluteServiceUri = new Uri(absoluteServiceUri.OriginalString + BinaryEndpointUri, UriKind.Absolute);
}
//Create the message encoding binding element - we'll specify binary encoding
var binaryMessageEncoding = new BinaryMessageEncodingBindingElement();
//Add the binding elements into a Custom Binding
var customBinding = new CustomBinding(binaryMessageEncoding, httpTransportBindingElement);
// Set send timeout
customBinding.SendTimeout = this.SendTimeout;
var factory = new ChannelFactory<IServiceAsync>(customBinding, new EndpointAddress(absoluteServiceUri, new AddressHeader[0]));
var channel = factory.CreateChannel();
channel.BeginGetStuff(Bla, results => { // Do something }, null);

Resolving constructor dependency on service used in NancyFX

I have the following bootstrap
public class NancyBootStrapper: DefaultNancyBootstrapper
{
protected override void ConfigureRequestContainer(TinyIoC.TinyIoCContainer container, NancyContext context)
{
base.ConfigureRequestContainer(container, context);
var ravenSession = container.Resolve< IRavenSessionProvider >().GetSession();
container.Register( ravenSession );
}
}
When my Nancy app tries to instantiate BlogService using the following constructor
public BlogService(IDocumentSession documentSession)
{
this.documentSession = documentSession;
}
the application blows up stating that it can't resolve document session, I have also tried the following within my test method (removing the constructor injection).
public void BuildCategories()
{
var container = TinyIoCContainer.Current;
documentSession = container.Resolve< IDocumentSession >();
documentSession.Store(new Category{Title = "test"});
documentSession.Store(new Category{Title = ".net"});
documentSession.SaveChanges();
}
This also blows up, pointing out that it can't resolve documentSession.
Now this is the first time I have used either NancyFX or TinyIoC so I could be doing something fundamentally wrong though I should mention that the documentSession does resolve within a Nancy module..
Can any one offer a fix or some suggestions?
When is the BlogService supposed to be instantiated? -My guess would be once for the application, in which case I believe you are registering the session in the wrong bootstrapper method, and should do it in ConfigureApplicationContainer.
I've been playing & digging into both NancyFx and the TinyIoC code bases and have figured out how to fix this issue... I don't like the fix... but hay it works :)
Basically, I am creating a RavenDB document session in the bootstrapper method configureRequestContainer as it is best practice to use the request as your unit of work scope.
Unfortunately anything that is auto wired by tinyIoC within configureApplicationContainer does not have any constructor injection performed using the child container being used by the Nancy request (this includes those that are marked as MultiInstance or as PerRequestSingleton.
To get around this, you need to re-register any components that depend on your per request components within the same child container.
As I said, I don't like the fix, but it is ultimately a fix :)

Autofac / MVC4 / WebApi (RC) Dependency Injection issue after upgrading from beta

var resolver = new AutofacWebApiDependencyResolver(container);
configuration.ServiceResolver.SetResolver(resolver);
after updating to ASP.NET MVC4 (RC) I get the following error:
'System.Web.Http.HttpConfiguration' does not contain a definition for
'ServiceResolver' and no extension method 'ServiceResolver' accepting
a first argument of type 'System.Web.Http.HttpConfiguration' could be
found (are you missing a using directive or an assembly reference?)
I realize after reading this (http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver) that these interfaces have changed, but I am not sure how to apply this change to how I use Autofac.
Do i need to wait for a new release from Autofac or is there another way I can get past this.
Edit:
As James Bradt mentions in his post below, the Autofac package has now been updated to fix this issue, so anyone coming across this thread in the future should probably try the new package first :)
Basically, with the new package you just need to do this in your global.asax.cs:
GlobalConfiguration.Configuration.DependencyResolver = new Autofac.Integration.WebApi.AutofacWebApiDependencyResolver(container);
/Edit
I just came across the same issue - I was able to resolve it in my situation by creating a simple IDependencyResolver implementation that wraps the existing AutofacDependencyResolver.
As the class name suggests, I'm treating this as a temporary resolution - the BeginScope and Dispose methods will need some work and are obviously not suitable for a production environment but this allows me to continue development until a proper solution emerges.
So, with those caveats, the IDependencyResolver implementation looks like this:
public class TemporaryDependencyResolver : IDependencyResolver
{
private readonly AutofacDependencyResolver _autofacDependencyResolver;
public TemporaryDependencyResolver(AutofacDependencyResolver autofacDependencyResolver)
{
_autofacDependencyResolver = autofacDependencyResolver;
}
public void Dispose()
{
}
public object GetService(Type serviceType)
{
return _autofacDependencyResolver.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _autofacDependencyResolver.GetServices(serviceType);
}
public IDependencyScope BeginScope()
{
return this;
}
}
and I set it like this in Global.asax.cs:
var container = builder.Build();
var resolver = new AutofacDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = new TemporaryDependencyResolver(resolver);
The AutoFac.WebApi package has been updated to (RC) - version 2.6.2.859
This appears to have been adjusted for the change in the dependencies between RC and Beta
I tried above solutions but didn't worked for me. Removing and Reinstalling these 2 specific packages solved the issue for me.
Microsoft.AspNet.WebApi.Tracing
Microsoft.AspNet.WebApi.OData