"The type TraceWriter must derive from ITraceWriter" after upgrading to Web API 2 - asp.net-web-api

We have a custom Web API ITraceWriter implementation named TraceWriter, registered as a service in the usual way in Application_Start.
After upgrading the Web API project to Web API 2, an HttpException is thrown in Application_Start:
The type TraceWriter must derive from ITraceWriter.
Parameter name: service
at System.Web.Http.Controllers.ServicesContainer.Replace(Type serviceType, Object service)
Of course, the TraceWriter actually is deriving from ITraceWriter, so what is the problem?

The TraceWriter implementation was located in a different project, which still referenced System.Web.Http, Version=4.0.0.0. Installing the latest Microsoft.AspNet.WebApi.Core package in this project solved the problem.

Related

How to Register MediatR in .NET 6 Web API where MediatR UsecCses are in separate project

I am working on C# Web API 6.0 project with MediatR. Since I am following clean architecture, I have separate project for Web API and Application. I have useCases in Application project with Queries, Commands and handler.
I have register MediatR to WebApplicationBuilder with reference of class 'ApplicationAssembly'. The 'ApplicationAssembly' class is inside Application project.
API Service Contrainer
public static class ServicesConfigurator
{
public static void Configure(WebApplicationBuilder builder)
{
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAutoMapper(typeof(ApplicationAssembly));
builder.Services.AddMediatR(typeof(ApplicationAssembly).GetTypeInfo().Assembly);
}
The above code don't work the way I register MediatR
Exception thrown: 'System.AggregateException' in Microsoft.Extensions.DependencyInjection.dll
if I changed to
builder.Services.AddMediatR(typeof(Program));
then I get following error
One or more errors occurred. (Error constructing handler for request of type MediatR.IRequestHandler`2[SalaryTracker.Application.UseCases.User.Queries.GetUser, SalaryTracker.Application.WrapperDTOs.UserWrapperDataView]. Register your handlers with the container. See the samples in GitHub for examples.)

Shiny + Prism + Platform Service Example

I am attempting to update a Prism 8.1 app to use Shiny v2.
In trying to turn one of my services into a Job I keep getting a container resolution error (using Unity). I am not sure what the pattern is for registering platform implementations of services. The Job has a service that is from my platform project but at the time the services.RegisterJob() is called I guess the platform initializer has not run.
Can someone post an example of how you are supposed to register platform implementations with Shiny?
Well, I'm not sure if this is the intended design but I solved the platform services this way.
I added a constructor parameter to my ShinyStartup like this:
public Startup(IPlatformInitializer platformInitializer) : base(PrismContainerExtension.Current)
{
_platformInitializer = platformInitializer;
}
and then in my AppDelegate I used this:
Shiny.ShinyHost.Init(new Shiny.ApplePlatform(), new Startup(new iOSInitializer()));
Where iOSInitializer is my Prism IPlatformInitializer.
Then in Startup I added:
protected override void RegisterServices(IContainerRegistry containerRegistry)
{
_platformInitializer.RegisterTypes(containerRegistry);
...
}
As far as the IJob not resolving dependencies when using RegisterJob, I moved job registration to App.OnStart using IJobManager.Register and it works. Also not sure if this is the intended design.
I did all my container wire up before calling RegisterJob and it still failed to resolve so there must be something under the covers that is happening in the Prism+Shiny world.

Why am I getting this ActivationException when using Simple Injector with WebApi Self Hosted in OWIN?

I have a very simple Web Api v2.2 self hosted in OWIN
public class StartUp
{
public void Configuration(IAppBuilder appBuilder, IConfigReader configReader)
{
var container = new Container();
container.Register<IConfigReader, ConfigReader>();
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
appBuilder.UseWebApi(config);
}
}
When I then use on my Main() as:
WebApp.Start(baseAddress, appBuilder =>
new StartUp().Configuration(appBuilder, new ConfigReader()));
However when I try to execute the last line appBuilder.UseWebApi(config); I get the following exception:
A first chance exception of type 'SimpleInjector.ActivationException'
occurred in SimpleInjector.dll
Additional information: The given type IHostBufferPolicySelector is
not a concrete type. Please use one of the other overloads to register
this type.
Complete Stack:
SimpleInjector.ActivationException occurred _HResult=-2146233088
_message=The given type IHostBufferPolicySelector is not a concrete type. Please use one of the other overloads to register this type.
HResult=-2146233088 IsTransient=false Message=The given type
IHostBufferPolicySelector is not a concrete type. Please use one of
the other overloads to register this type. Source=SimpleInjector
StackTrace:
at SimpleInjector.Advanced.DefaultConstructorResolutionBehavior.VerifyTypeIsConcrete(Type
implementationType) InnerException:
The problem is not that single interface it looks like SimpleInjector is trying to find a binding for Every Single Interface; If I provide a dummy implementation for IHostBufferPolicySelector it throws for some other interface e.g. IExceptionHandler etc.
There is a related thread HERE but I am not sure how it relates to SimpleInjector?
The Self host is a Console App which has the following packages installed:
Simple Injector ASP.NET Web API Integration v2.61
Simple Injector Execution Context Scoping v2.61
Simple Injector v2.61
OWIN v1.0
Microsoft.Owin v2.0.2
Microsoft.Owin.Hosting v2.0.2
Microsoft ASP.NET Web API 2.2 OWIN v5.2.2
Microsoft ASP.NET Web API 2.2 OWIN Self Host v5.2.2
According to Simple Injector:
The exceptions you are showing are 'first chance exceptions'. These
exceptions are thrown by Simple Injector but they are caught and
processed by Simple Injector and they won't bubble up the call stack.
It is possible that you see them in some debugger output window, but
they are quite normal and nothing to worry about.
It turned out that the exception only bubbles up when I have the Common Language Runtime Exceptions checked to thrown
When I untick the checkbox everything behaves as normal! which is weird! also wrapping it in a Try-Catch (Exception) doesn't even catch it which makes it even more interesting/werid!

Error using Autofac with ASP.NET Web API RC and ASP.NET MVC3

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.

ASP .Net 4 Web Api RC + Autofac manual resolving

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

Resources