IDependency and Generic Types

Topics: Writing modules
Mar 23, 2011 at 4:35 PM

Hi team,

I have a generic interface like

 

IMegaContentPartService<T> : IDependency
    where T : MegaContentPart
{
    T Get(int id);
}

 

and a driver that uses it, but Exception is throwed in runtime saying that Type resolution is failed for this interface. It looks like that Orchard isn't capable to find and appropriate register my generic interface marked with IDependency, in the meanwhile non-generic version works fine.

Could you please advice how should I deal with generic types? Thanks!

Coordinator
Mar 23, 2011 at 4:47 PM

That should work just fine (IRepository is an example of a generic dependency). Are you sure the file containing this is getting picked up by the compiler?

Mar 24, 2011 at 9:47 AM

Yep, all types are placed in my module. Driver that used IMegaContentPartService, service and its implementation itself.

 

Server Error in '/orchard-branch' Application.

None of the constructors found with policy 'Orchard.Environment.AutofacUtil.DynamicProxy2.ConstructorFinderWrapper' on type 'Dedi.Community.Enablement.Portals.Handlers.EnablementStepPartHandler' can be invoked with the available services and parameters:
Constructor 'Void .ctor(Dedi.Community.Enablement.Portals.Services.IEnablementPartService, Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase], System.Web.Routing.RequestContext)' parameter resolution failed at parameter 'Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase] enablementStepService'.

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: Autofac.Core.DependencyResolutionException: None of the constructors found with policy 'Orchard.Environment.AutofacUtil.DynamicProxy2.ConstructorFinderWrapper' on type 'Dedi.Community.Enablement.Portals.Handlers.EnablementStepPartHandler' can be invoked with the available services and parameters:
Constructor 'Void .ctor(Dedi.Community.Enablement.Portals.Services.IEnablementPartService, Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase], System.Web.Routing.RequestContext)' parameter resolution failed at parameter 'Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase] enablementStepService'.

Source Error: 

Line 42:         public IEnumerable<EnablementPart> Get(VersionOptions versionOptions)
Line 43: {
Line 44: return this.contentManager.Query<EnablementPart, EnablementPartRecord>(versionOptions)
Line 45: .Join<RoutePartRecord>()
Line 46: .OrderBy(br => br.Title)


Source File: d:\Projects\Dedi.Community.Dev.Orchard.Branch\orchard\src\Orchard.Web\Modules\Dedi.Community.Enablement.Portals\Services\EnablementPartService.cs    Line: 44 

Stack Trace: 

[DependencyResolutionException: None of the constructors found with policy 'Orchard.Environment.AutofacUtil.DynamicProxy2.ConstructorFinderWrapper' on type 'Dedi.Community.Enablement.Portals.Handlers.EnablementStepPartHandler' can be invoked with the available services and parameters:
Constructor 'Void .ctor(Dedi.Community.Enablement.Portals.Services.IEnablementPartService, Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase], System.Web.Routing.RequestContext)' parameter resolution failed at parameter 'Dedi.Community.Enablement.Portals.Services.IEnablementStepService`1[Dedi.Community.Enablement.Portals.Models.EnablementStepPartBase] enablementStepService'.]
Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) +578
Autofac.Core.Resolving.ComponentActivation.Activate(IEnumerable`1 parameters) +89
Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func`1 creator) +122
Autofac.Core.Resolving.ComponentActivation.Execute(IEnumerable`1 parameters) +255
Autofac.Core.Resolving.ResolveOperation.Resolve(ISharingLifetimeScope activationScope, IComponentRegistration registration, IEnumerable`1 parameters) +246
System.Linq.WhereSelectArrayIterator`2.MoveNext() +110
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +488
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +104
Autofac.Features.Collections.<>c__DisplayClass4.<RegistrationsFor>b__0(IComponentContext c, IEnumerable`1 p) +197
Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) +74
Autofac.Core.Resolving.ComponentActivation.Activate(IEnumerable`1 parameters) +89
Autofac.Core.Resolving.ComponentActivation.Execute(IEnumerable`1 parameters) +141
Autofac.Core.Resolving.ResolveOperation.Resolve(ISharingLifetimeScope activationScope, IComponentRegistration registration, IEnumerable`1 parameters) +246
Autofac.Builder.<>c__DisplayClass1`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p) +15
Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) +74
Autofac.Core.Resolving.ComponentActivation.Activate(IEnumerable`1 parameters) +89
Autofac.Core.Resolving.ComponentActivation.Execute(IEnumerable`1 parameters) +141
Autofac.Core.Resolving.ResolveOperation.Resolve(ISharingLifetimeScope activationScope, IComponentRegistration registration, IEnumerable`1 parameters) +246
Autofac.Core.Lifetime.LifetimeScope.Resolve(IComponentRegistration registration, IEnumerable`1 parameters) +276
Autofac.ResolutionExtensions.Resolve(IComponentContext context, Service service, IEnumerable`1 parameters) +221
Autofac.ResolutionExtensions.Resolve(IComponentContext context, IEnumerable`1 parameters) +117
Orchard.ContentManagement.DefaultContentManager.New(String contentType) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\ContentManagement\DefaultContentManager.cs:73
Orchard.ContentManagement.DefaultContentManager.Get(Int32 id, VersionOptions options) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\ContentManagement\DefaultContentManager.cs:132
System.Linq.WhereSelectListIterator`2.MoveNext() +232
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +472
System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
Orchard.ContentManagement.ContentQuery`1.Orchard.ContentManagement.IContentQuery<T>.List() in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\ContentManagement\DefaultContentQuery.cs:184
Dedi.Community.Enablement.Portals.Services.EnablementPartService.Get(VersionOptions versionOptions) in d:\Projects\Dedi.Community.Dev.Orchard.Branch\orchard\src\Orchard.Web\Modules\Dedi.Community.Enablement.Portals\Services\EnablementPartService.cs:44
Dedi.Community.Enablement.Portals.Services.EnablementPartService.Get() in d:\Projects\Dedi.Community.Dev.Orchard.Branch\orchard\src\Orchard.Web\Modules\Dedi.Community.Enablement.Portals\Services\EnablementPartService.cs:39
Dedi.Community.Enablement.Portals.Routing.EnablementSlugConstraintUpdator.Refresh() in d:\Projects\Dedi.Community.Dev.Orchard.Branch\orchard\src\Orchard.Web\Modules\Dedi.Community.Enablement.Portals\Routing\EnablementSlugConstraintUpdator.cs:39
Dedi.Community.Enablement.Portals.Routing.EnablementSlugConstraintUpdator.Orchard.Environment.IOrchardShellEvents.Activated() in d:\Projects\Dedi.Community.Dev.Orchard.Branch\orchard\src\Orchard.Web\Modules\Dedi.Community.Enablement.Portals\Routing\EnablementSlugConstraintUpdator.cs:25

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner) +0
System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner) +152
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +393
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +38
Orchard.Events.DefaultOrchardEventBus.TryInvokeMethod(IEventHandler eventHandler, Type interfaceType, String methodName, IDictionary`2 arguments, IEnumerable& returnValue) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\DefaultOrchardEventBus.cs:86
Orchard.Events.DefaultOrchardEventBus.TryInvoke(IEventHandler eventHandler, String interfaceName, String methodName, IDictionary`2 arguments, IEnumerable& returnValue) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\DefaultOrchardEventBus.cs:76
Orchard.Events.DefaultOrchardEventBus.TryNotifyHandler(IEventHandler eventHandler, String messageName, String interfaceName, String methodName, IDictionary`2 eventData, Boolean failFast, IEnumerable& returnValue) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\DefaultOrchardEventBus.cs:62
Orchard.Events.<NotifyHandlers>d__0.MoveNext() in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\DefaultOrchardEventBus.cs:39
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +488
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +104
Orchard.Events.DefaultOrchardEventBus.Notify(String messageName, IDictionary`2 eventData) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\DefaultOrchardEventBus.cs:25
Orchard.Events.EventsInterceptor.Intercept(IInvocation invocation) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Events\EventsInterceptor.cs:24
Orchard.Environment.DefaultOrchardShell.Activate() in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Environment\DefaultOrchardShell.cs:40
Orchard.Environment.DefaultOrchardHost.<CreateAndActivate>b__1(ShellSettings settings) in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Environment\DefaultOrchardHost.cs:100
System.Linq.WhereSelectArrayIterator`2.MoveNext() +110
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +488
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +104
Orchard.Environment.DefaultOrchardHost.BuildCurrent() in d:\TeamCity\Projects\Orchard-1.x\src\Orchard\Environment\DefaultOrchardHost.cs:88

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +3988565
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529072
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4784373



Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

Coordinator
Mar 25, 2011 at 12:28 AM

I'd need to see more code to understand what's going on. Can you show the code that declares and injects the dependency, as well as its type definition?

Mar 28, 2011 at 1:33 PM

 

Service
 public interface IEnablementStepService<T> : IDependency
        where T : EnablementStepPartBase
    {
        T Get(EnablementPart enablementPart, string slug);
        IEnumerable<T> Get(EnablementPart enablementPart);
    }
Handler
  public class EnablementStepPartHandler : ContentHandler
    {
        private readonly IEnablementPartService enablementPartService;
        private readonly IEnablementStepService<EnablementStepPartBase> enablementStepService;

        public EnablementStepPartHandler(
            IEnablementPartService enablementPartService, 
            IEnablementStepService<EnablementStepPartBase> enablementStepService, 
            RequestContext requestContext)
        {
            this.enablementPartService = enablementPartService;
            this.enablementStepService = enablementStepService;
        }
}

 

 

Coordinator
Mar 29, 2011 at 12:58 AM

And the implementation of the service?

Sep 12, 2011 at 10:43 PM
Edited Sep 12, 2011 at 11:16 PM

Sorry for reviving this post - I've moved my comment into a new thread bc it is not related to Generics.

Dec 6, 2011 at 2:38 AM

Sorry to zombie this post but I had a similar issue and figured a contribution was in order.

 

I had a generic interface which was not being registered auto-magically by Autofac. This caused a few choice words to fly out of my mouth on more than one occasion. I then decided to see how the supreme beings of the Orchard Project handled it. After a little poking around it did not take me long to start looking into the IRepository interface which lead me to "DataModule.cs" .  That’s when the answer became apparent. In the root of the module for your service/interface create a file named "DataModule.cs" or whatever makes sense to you, inherit "Autofac.Module", and override Load. Next pass your generic interface/service to builder.RegisterGeneric. Then modify the Priority for each dependent module’s “Module.txt”. Finally grab a beer and reflect that nothing is ever as hard as it first appears.

 

That's pretty much it.

Developer
Dec 6, 2011 at 8:46 AM

Generic dependencies are currently not automatically registered,see the issue (and the discussion linked there). Basically as far as I understand the problem is that all dependencies are registered with Autofac's RegisterType(), but generics require RegisterGeneric(). So you have to register such types manually with a Module, just as jtstogner said.

Coordinator
Jan 16, 2012 at 4:18 PM

Just a small update on the post to say that the issue has been fixed, autofac got upgraded.

Developer
Jan 16, 2012 at 4:40 PM

That's cool, but doesn't fix the issue of generic dependencies IMO, as this is a matter of how dependencies are registered: generics are not auto-registered with RegisterGeneric().