i try to configure my NServiceBus for a WebApi. I've tried this one: https://coderkarl.wordpress.com/2012/03/16/injecting-nservicebus-into-asp-net-webapi/
The Problem is the Syntax has been changed in the newest NServiceBus-Versin. I can't use the Functions for the Configure-Class because they will be removed in further Versions. The new way to configure the Bus is using the BusConfiguration-Class but i have no idea how.
Here is the older Code:
public static Configure ForWebApi(this Configure configure)
{
// Register our http controller activator with NSB
configure.Configurer.RegisterSingleton(typeof(IHttpControllerActivator),
new NSBHttpControllerActivator());
// Find every http controller class so that we can register it
var controllers = Configure.TypesToScan
.Where(t => typeof(IHttpController).IsAssignableFrom(t));
// Register each http controller class with the NServiceBus container
foreach (Type type in controllers)
configure.Configurer.ConfigureComponent(type, ComponentCallModelEnum.Singlecall);
// Set the WebApi dependency resolver to use our resolver
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NServiceBusResolverAdapter(configure.Builder));
// Required by the fluent configuration semantics
return configure;
}
And Application_Start():
AreaRegistration.RegisterAllAreas();
// Use LocalDB for Entity Framework by default
Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
Configure.WithWeb()
.DefaultBuilder()
.ForWebApi() // <------ here is the line that registers it
.Log4Net()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(false)
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
Does someone has managed it for the NServiceBus Version 5?
As wlabaj says, the documentation on the particular website says it all. Almost.
We use AutoFac so we don't need any direct reference to IBus or ISendOnlyBus and therefor we do this
ContainerBuilder builder = new ContainerBuilder();
var container = builder.Build();
configuration.UseContainer<AutofacBuilder>(x => x.ExistingLifetimeScope(container));
What we do in WebAPI and ASP.NET applications is this
NServiceBus.Bus.CreateSendOnly(configuration);
Because it's not a good practice to expect reply messages to come back after sending them.
Here you can see 3.0 vs 4.0 vs 5.0 configuration syntax. At the top of the page you have a link to download code samples.
The examples are for ASP .NET though, so you'll need to tweak it slightly for WebAPI. Let me know if you need further help with that.
ForWebApi was never a part of NServiceBus, this was an extension method from the sample that was used to configure NServiceBus dependency resolver to instantiate controllers. The way how it was done is shown here.
There is no need to use NServiceBus resolver since it is just a wrapper around another container. By default it uses Autofac, so you can just use Autofac to work for you in the whole application.
Autofac WebAPI integration is properly described in the documentation.
NServiceBus documentation has a page about using your own container.
This is a very well known setup that you can easily implement.
Related
I had a webapi in which I was using app.CreatePerOwinContext in startup.cs file but I want to migrate that webapi to .net core 2.1. So I have stuck at this point as I can't fine any alternate for CreatePerOwinContext.
Here is my webapi code:
public static UserManager<IdentityUser> Create(IdentityFactoryOptions<UserManager<IdentityUser>> options, IOwinContext context)
{
var manager = new UserManager<IdentityUser>(new UserStore());
return manager;
}
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<UserManager<IdentityUser>>(Create);
...
}
So how can I convert the above code in .net core 2.1?
That method was used as a service locator to load up dependencies and then access them throughout your code. Service location on its own is considered an anti-pattern, and is not recommended for use in the vast majority of real world situations.
Instead, people use IOC containers now to manage their dependency injection. In ASP.NET MVC Core, there's now a lightweight and "good enough" IOC container provided for you as part of the framework.
Microsoft provides an overview in this article, but the short version is that in your Startup.cs you register your dependency tree under ConfigureServices (usually using an extension method so Startup.cs doesn't get too large).
After you've registered your dependencies, you load them either through property injection, constructor injection, or method parameter injection. This results in cleaner code that is more maintainable than standard service location.
Edit:
If you truly insist on managing a service locator either because the technical debt is acceptable or because the business case warrants the current design, then I suggest you transition your work from OwinContext over to HttpContext.
In ASP.NET Core, you access the HttpContext by injecting the HttpContextAccessor into your class, and changing your OwinContext calls to pull from the key value store in HttpContext.
Instructions for injecting HttpContextAccessor can be found in this SO answer. Simply store KVPs using HttpContext.Current.Application["myObject"].
I don't recommend doing this, but I'm willing to share it because I understand the reality of deadlines vs the idealism of architecture.
I used the MVC integration from autofac like this:
...
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
But now I want to recreate the solution with the new Web Api RTM.
And I want to use the new AutofacWebApiDependencyResolver class.
But if I do this with AutofacWebApiDependencyResolver i got this error:
The type Autofac.Integration.WebApi.AutofacWebApiDependencyResolver
does not appear to implement
Microsoft.Practices.ServiceLocation.IServiceLocator.
I read that i have to do this now for setting the resolver:
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
But if I set it with '=', it is not set. Its still the DefaultResolver...
If I use the MVC AutofacDependencyResolver class again, it works.
Are were still problems with autofac and web api rtm? (the current integration is RC version)
ASP.Net Wep.API and ASP.NET MVC uses two different IDependencyResolver (because they designed the Wep.API to not depend on ASP.NET MVC) so you need to setup both:
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container);
So the AutofacDependencyResolver is needed to inject decencies to regular MVC Controller derived controllers.
And the AutofacWebApiDependencyResolver is needed to inject dependencies to the Web.API ApiController derived controllers.
And don't forget to register your Api controllers in your container builder with the call (it differs from usual builder.RegisterControllers method):
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
Following is a very good example
Using Autofac with Web Api
I added ASP.NET Web API RC to my MVC3 project using NuGet:
Install-Package AspNetWebApi
Then I configured it. In Global.asax.cs:
// configure regular controllers
var configuration = GlobalConfiguration.Configuration;
var container = Bootstrapper.ConfigureContainer(configuration);
containterProvider = new ContainerProvider(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Set the dependency resolver implementation for Web API.
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolver;
And in Boostrapper.ConfigureContainer(...) I added:
// I register my types as InstancePerLifetimeScope()
// but I also tried .InstancePerHttpRequest().InstancePerApiRequest()
// to the same end
builder.RegisterType<SomeService>()
.AsImplementedInterfaces().InstancePerLifetimeScope();
// Register API controllers using assembly scanning.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(config);
This is described here and here.
I also updated Autofac, Autofac.Web, Autofac.Mvc3 packages using NuGet and installed Autofac.WebApi package.
With this configuration I tried running my ApiController and got the following error:
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
Then as I read this comment from Alex Meyer-Gleaves:
I suspect you are using the Web API package with MVC3 and this is causing the problem. In the MVC3 integration the tag for the InstancePerHttpRequest lifetime scope was "httpRequest". It was in the MVC4 Beta and Web API Beta packages that I changed both InstancePerHttpRequest and InstancePerApiRequest to use the common tag "AutofacWebRequest". You can grab the MVC4 integration package from NuGet using Autofac.Mvc4.
source article with comment
So following the advice from Alex I got the package Autofac.Mvc4 but it works only with Mvc4 and my project wouldn't build. I then grabbed the source code of Autofac to build Autofac.Mvc4 against Mvc3:
hg clone https://code.google.com/p/autofac/ --branch "MVC4 beta" C:\my\path
After using this assembly as my reference ApiController started working but regular Controllers worked ok only for a single controller action call. When the view called Html.RenderAction(...) and when I refresh or navigate to another controller action it crashes with this error:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
I thought building from the newest source for Autofac.Mvc4 version 2.6.2.859 against Mvc3 could help but I can't find the source for that. Or maybe there's something else wrong in here?
I found the problem. I also used Autofac.Integration.Web to inject dependencies into custom Membership and Role providers. But in WebLiftime.cs there was this line:
public static readonly object Request = "httpRequest";
Once I changed it to:
public static readonly object Request = "AutofacWebRequest";
and used the built assembly everything works fine and I get no errors :)
I believe this constant value should the same as in all projects Autofac.Integration.Web, Autofac.Integration.Mvc and 'Autofac.Integration.WebApi for Mvc4 so this supposedly is a bug.
I'm trying to use depedency resolver inside a Web Api method. This worked fine and works fine with classic ASP.NET MVC with the DepedencyResolver.GetService()
But I can't get this to work inside WepApi methods.
My registration register all instances as InstancePerApiRequest and if I add any of all the types I have registred in my bootstrapper on the constructor of my WebAPiConroller thay inject fine but not anymore when calling them inside.
Like this in my say Get Method
var userRepository = (IUserRepositoryu)GlobalConfiguration
.Configuration.DependencyResolver.GetService(typeof(IUserRepository));
I got the no scope WebRequest error. The strange thing is that it worked fine in Beta before they change it all to the GlobalConfiguration.
So my question is, how can I activate my Autofac registered assemblies in the lifetime scope of my webAPi as before?
My error:
"No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself."
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolver;
In Web API the global dependency resolver is used to access global instances. Per-request services come from a dependency scope that Web API creates to handle the request. I'm not sure that there is any way in Web API to access the current dependency scope - it would be interesting to know.
The best option here is to just use dependency injection rather than calling the resolver directly like this. Which part of your code needs to make this call?
AutoFac has integration with ASP.NET WebAPI consider to use it.
Also dependecy resolver for WebAPi is slightly different to ASP.NET MVC, so make shure, that you have implemented resolver suitable for WebAPI and added it to WebAPI configuration.
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
As the error indicated, you must always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime. The correct way is getting the dependency from current web api request:
// Get the request lifetime scope so you can resolve services.
var requestScope = Request.GetDependencyScope();
// Resolve the service you want to use.
var userRepository = requestScope.GetService(typeof(IUserRepository)) as IUserRepository;
See more from Autofac offical documentations:
http://docs.autofac.org/en/latest/integration/webapi.html#standard-web-api-filter-attributes-are-singletons
I am creating a MVC3 website that will expose a REST API using WCF Web API.
To register routes to the REST API I add code to the Global.asax similar to the code below.
routes.MapServiceRoute<RelationsService>("relations");
This works well enough but i need to use a DI approach to inject the dependencies that the Service depends on.
As you can see in the code above the MVC framework is creating the instance of the RelationsService but this should be done by the DI container.
Does anyone know how to configure MVC3 so that my own DI container is used for creating the instances of the Services?
You have to extend your current service registration call with an IHttpHostConfigurationBuilder that has been created with an IResourceFactory.
var configurationBuilder = HttpHostConfiguration.Create()
.SetResourceFactory(new ResourceFactory());
routes.MapServiceRoute<RelationsService>("relations", configurationBuilder);
Then if you for instance use StructureMap as preferred IoC/DI tool you can just ask for the service in the GetInstance method.
public class ResourceFactory : IResourceFactory
{
public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
{
return ObjectFactory.GetInstance(serviceType);
}
}