I am registering my interface in App.config. But while resolving, I am getting the below exception.
Microsoft.Practices.Unity.ResolutionFailedException
HResult=0x80131500
Message=Resolution of the dependency failed, type = "Philips.DI.Interfaces.UW.DtoModel.IModelProvider`1[Philips.DI.UW.PatientOrchestrator.Interfaces.PatientScheduleDataModel]", name = "LoginPage".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Philips.DI.Interfaces.UW.DtoModel.IModelProvider`1[Philips.DI.UW.PatientOrchestrator.Interfaces.PatientScheduleDataModel], is an interface and cannot be constructed. Are you missing a type mapping?
At the time of the exception, the container was:
Resolving Philips.DI.Interfaces.UW.DtoModel.IModelProvider`1[Philips.DI.UW.PatientOrchestrator.Interfaces.PatientScheduleDataModel],LoginPage
var proxy = container.Resolve<T>("LoginPage", new ResolverOverride[] {
new ParameterOverride("unityContainer", container),new ParameterOverride("serviceEndPoint", serviceEndPoint)});
public SyncProxy(IUnityContainer unityContainer, ServiceEndPoint serviceEndPoint) : base(unityContainer, serviceEndPoint)
{
_clientDataSyncWrapper = unityContainer.Resolve<ClientDataSyncWrapper>();
RegisterPushMessages();
}
[InjectionConstructor]
public SyncProxy(IUnityContainer unityContainer, string endPoint) : base(unityContainer, endPoint)
{
_clientDataSyncWrapper = unityContainer.Resolve<ClientDataSyncWrapper>();
RegisterPushMessages();
}
Related
Im trying to implement CQRS pattern to my app. So I found how to register all command handlers from assembly here : Autofac resolve dependency in CQRS CommandDispatcher
But it doesnt work well for me. Here is the code:
containerBuilder.RegisterAssemblyTypes(assembly)
.AsClosedTypesOf(typeof(ICommandHandler<>));
containerBuilder.RegisterAssemblyTypes(assembly)
.AsClosedTypesOf(typeof(IQueryHandler<,>));
Handlers factory
public class CqrsHandlerFactory : ICqrsHandlerFactory
{
private readonly IContainer container;
public CqrsHandlerFactory(IContainer container)
{
this.container = container;
}
public ICommandHandler<TCommand> GetCommandHandler<TCommand>(TCommand command) where TCommand : class, ICommand
{
return container.Resolve<ICommandHandler<TCommand>>();
}
public IQueryHandler<TQuery, object> GetQueryHandler<TQuery>(TQuery query) where TQuery : class, IQuery
{
return container.Resolve<IQueryHandler<TQuery, object>>();
}
}
Bus
public class CqrsBus : ICqrsBus
{
private readonly ICqrsHandlerFactory cqrsHandlerFactory;
public CqrsBus(ICqrsHandlerFactory cqrsHandlerFactory)
{
this.cqrsHandlerFactory = cqrsHandlerFactory;
}
public void ExecuteCommand(ICommand command)
{
var handler = cqrsHandlerFactory.GetCommandHandler(command);
if (handler == null)
throw new NotImplementedHandlerException(string.Format("Cannot find handler for {0}", command.GetType()));
handler.Handle(command);
}
public TResult RunQuery<TResult>(IQuery query)
{
var handler = cqrsHandlerFactory.GetQueryHandler(query);
if (handler == null)
throw new NotImplementedHandlerException(string.Format("Cannot find handler for {0}", query.GetType()));
return (TResult)handler.Handle(query);
}
}
Exception
An exception of type 'Autofac.Core.Registration.ComponentNotRegisteredException' occurred in Autofac.dll but was not handled in user code
Additional information: The requested service 'PromocjeWsieciowkach.Messaging.Core.ICommandHandler`1[[PromocjeWsieciowkach.Messaging.Core.ICommand, PromocjeWsieciowkach.Messaging.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
Stacktrace
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable1 parameters)
at PromocjeWsieciowkach.Messaging.Factories.CqrsHandlerFactory.GetCommandHandler[TCommand](TCommand command) in C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach.Messaging\Factories\CqrsHandlersFactory.cs:line 17
at PromocjeWsieciowkach.Messaging.Bus.CqrsBus.ExecuteCommand(ICommand command) in C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach.Messaging\Bus\CqrsBus.cs:line 17
at PromocjeWsieciowkach.Controllers.PostController.Index() in C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach\Controllers\PostController.cs:line 20
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__28.MoveNext()
So what i'am doing wrong?
Your code and the exception message clearly show the problem. In summary, your exception message explains that:
The requested service 'ICommandHandler<ICommand>' has not been registered.
In other words, you are requesting an ICommandHandler<ICommand> instead of an ICommandHandler<TestCommand>. This can be seen here:
public void ExecuteCommand(ICommand command)
{
var handler = cqrsHandlerFactory.GetCommandHandler(command);
// ...
}
The C# compiler applied type inference to the GetCommandHandler<T> call. So the following code is the actual call:
var handler = cqrsHandlerFactory.GetCommandHandler<ICommand>(command);
You should change the ICrqsBus.ExecuteCommand method to the following:
public void ExecuteCommand<TCommand>(TCommand command)
{
// You can merge the factory and your CqrsBus. Splitting them is useless.
var handler = cqrsHandlerFactory.GetCommandHandler<TCommand>();
// You don't need then null check; Autofac never returns null.
handler.Handle(command);
}
If you can't make the ExecuteCommand method generic (e.g. because you don't know the command type at compile time), you should build the generic types using the reflection API as follows:
public class CqrsBus : ICqrsBus
{
private readonly IComponentContext context;
public CqrsBus(IComponentContext context)
{
this.context = context;
}
public void ExecuteCommand(ICommand command)
{
Type handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
dynamic handler = this.context.Resolve(handlerType);
void handler.Execute((dynamic)command);
}
}
It's also worth noting that if your using nopcommerce and adding a service, the same error is generated if you forget to add your service in the dependancy registrar.
builder.RegisterType<YourService>().As<IYourService>().InstancePerLifetimeScope();
Just came across this myself, and the following quote:
The requested service 'ICommandHandler' has not been registered."
Made me realise about the dependancy registrar.
Thanks Steven
I am seeing an issue in using of unity in controller constructor. Here are the details -
In unit configuration (unity.config)– here is what I am doing –
container.RegisterType<ISessionWrapper, SessionWrapper>()
In the Controller constructor
public OnboardingController( ISessionWrapper sessionwrapper )
{
SessionWrapper = sessionwrapper;
}
SessionWrapper
public interface ISessionWrapper
{
string Brand { get; set; }
//string CurrenSessionCulture { get; set; }
}
public class SessionWrapper : ISessionWrapper
{
public string Brand
{
get;
set;
}
}
Error occuring in doing this
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.****
When I change the Controller Constructor definition like this it is all working fine.
public OnboardingController()
: this(new SessionWrapper())
{
//
}
You need to use a custom ControllerFactory using Unity to resolve instances of your controller classes. The default ControllerFactory used by MVC requires that the controller classes have a parameterless constructor.
A custom ControllerFactory using Unity looks like
public class UnityControllerFactory : DefaultControllerFactory {
private readonly IUnityContainer _container;
public UnityControllerFactory (IUnityContainer container) {
_container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
if (controllerType != null) {
return _container.Resolve(controllerType) as IController;
}
else {
return base.GetControllerInstance(requestContext, controllerType);
}
}
}
On application start (normally in the global.asax) you register your ControllerFactory in the MVC Runtime using the following code
var container = // initialize your unity container
var factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);
I'm trying to resolve a concrete class having a container with autofac
My setup is something like this
[TestInitialize]
public void Setup()
{
_automoqer = new AutoMoqer();
_distributeProcessSink = _automoqer.Resolve<DistributedSaveHistorySink>();
}
and my concrete class looks like this
private readonly Func<string, IConsolidationContext, IConsolidationStore> _consolidationStoreFactory;
public DistributedSaveHistorySink(Func<string, IConsolidationContext, IConsolidationStore> consolidationStoreFactory)
{
_consolidationStoreFactory = consolidationStoreFactory;
}
Initialization method xx threw exception.
Microsoft.Practices.Unity.ResolutionFailedException:
Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency
failed, type = "xx.DistributedSaveHistorySink", name = "(none)".
Exception occurred while: while resolving.
Exception is: TargetInvocationException - Exception has been thrown by the target
of an invocation.
also my container configuration looks like this
builder.RegisterType<DistributedSaveHistorySink>()
.Keyed<IProcessSink<MergeMessage>>(PipelineType.Default)
.PropertiesAutowired();
I got an error on the creation of an api controller due to that I didn't set up autofac for webapi.
However, I can't seem to catch the exception anywhere.
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'MyWeb.Web.Controllers.MyController' does not have a default constructor
</ExceptionMessage>
<ExceptionType>System.ArgumentException</ExceptionType>
<StackTrace>
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
</Error>
I tried adding WebApi contrib for Elmah, then I added this:
config.Filters.Add(new Elmah.Contrib.WebApi.ElmahHandleErrorApiAttribute());
Didn't make elmah register the exception.
I added the following to global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
Didn't make any difference at all.
How can I handle errors happening before the controllers are called?
I wonder if this exception is just being added to the content of the HttpResponseMessage but is not actually being thrown as an exception. When implementing a dependency resolver class for use during constructor instantiation, it usually makes sense to attempt resolution, catch exceptions and return null.
For example, in non-API MVC controllers I've often used something like this:
public class UnityDependencyResolver : IDependencyResolver
{
public readonly IUnityContainer Container;
public UnityDependencyResolver(IUnityContainer container)
{
Container = container;
}
#region IDependencyResolver Members
public object GetService(Type serviceType)
{
try
{
return Container.Resolve(serviceType);
}
catch (Exception ex)
{
if (ex.InnerException is TypeInitializationException)
throw ex.InnerException;
return null;
}
}
...
I am using ServiceStack in standalone mode. It is now giving a TypeInitialzationException when executing Apphost.Start().
At the time, I was working on implementing some custom filters, but removing the annotation from the only filtered DTO class did not solve the problem.
The stack trace does not show any of my classes involved, and the failing class is the JsvReader which I don't use explicitly.
How can prevent this problem?
Note: I just used nuget to update all packages, so this is current as of now, 3.9.43 for all ServiceStack components.
Exception Detail
System.TypeInitializationException occurred
HResult=-2146233036
Message=The type initializer for 'ServiceStack.Text.Jsv.JsvReader`1' threw an exception.
Source=ServiceStack.Text
TypeName=ServiceStack.Text.Jsv.JsvReader`1
StackTrace:
at ServiceStack.Text.Jsv.JsvReader`1.GetParseFn()
at ServiceStack.Text.Jsv.JsvReader.GetParseFn(Type type)
at ServiceStack.ServiceModel.Serialization.StringMapTypeDeserializer..ctor(Type type)
at ServiceStack.ServiceHost.RestPath..ctor(Type requestType, String path, String verbs, String summary, String notes)
at ServiceStack.ServiceHost.ServiceController.RegisterRestPaths(Type requestType)
at ServiceStack.ServiceHost.ServiceController.RegisterCommon(Type serviceType, Type requestType, Type responseType)
at ServiceStack.ServiceHost.ServiceController.RegisterNService(ITypeFactory serviceFactoryFn, Type serviceType)
at ServiceStack.ServiceHost.ServiceController.Register(ITypeFactory serviceFactoryFn)
at ServiceStack.ServiceHost.ServiceManager.Init()
at ServiceStack.WebHost.Endpoints.Support.HttpListenerBase.Init()
at ArdWebServer.Program.Main(String[] args)
InnerException: System.TypeInitializationException
HResult=-2146233036
Message=The type initializer for 'ServiceStack.Text.Common.DeserializeSpecializedCollections`2' threw an exception.
Source=ServiceStack.Text
TypeName=ServiceStack.Text.Common.DeserializeSpecializedCollections`2
StackTrace:
at ServiceStack.Text.Common.DeserializeSpecializedCollections`2.get_Parse()
at ServiceStack.Text.Common.JsReader`1.GetCoreParseFn[T]()
at ServiceStack.Text.Common.JsReader`1.GetParseFn[T]()
at ServiceStack.Text.Jsv.JsvReader`1..cctor()
InnerException: System.NullReferenceException
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=ServiceStack.Text
StackTrace:
at ServiceStack.Text.PlatformExtensions.GenericTypeArguments(Type type)
at ServiceStack.Text.Common.DeserializeSpecializedCollections`2.GetGenericEnumerableParseFn()
at ServiceStack.Text.Common.DeserializeSpecializedCollections`2.GetParseFn()
at ServiceStack.Text.Common.DeserializeSpecializedCollections`2..cctor()
InnerException:
My App host
public class AppHost : AppHostHttpListenerBase
{
public AppHost() : base("IAM Tools Service Stack Host", typeof (Tims.Global).Assembly)
{
CatchAllHandlers.Add(
(httpMethod, pathInfo, filePath) =>
Tims.Support.StaticFileHandler.Factory(
Params.Instance.HttpDataDir,
"/",
pathInfo
)
);
}
public override void Configure(Funq.Container container)
{
SetConfig(new EndpointHostConfig()
{
DebugMode = true,
WriteErrorsToResponse = true
});
}
}