locked
Unity container works within Asp.net project but not within class library it calls. RRS feed

  • Question

  • User-454803633 posted

    I have a solution with an asp.net project and several class libraries.  I am using Unity 2.0 in all the projects.  Unity 2.0 seems to work within the HelpfulQuiz web asp.net project, but not within the HelpfulQuizCore class library it utilizes.  I've spent several days trying to figure this out and would appreciate your kind assistance.  Here is the error:

     

    Server Error in '/' Application.

    The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?

    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.InvalidOperationException: The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?

    Source Error: 

    Line 30:             container2 = new UnityContainer().LoadConfiguration();
    Line 31:             //IRedirector test = container.Resolve<IRedirector>();
    Line 32:             pictureRepository = container2.Resolve<IPictureRepository>();
    Line 33:             productRepository = container2.Resolve<IProductRepository>();
    Line 34:             productScoreRepository = container2.Resolve<IProductScoreRepository>();


    Source File: c:\users\tim\documents\visual studio 2010\Projects\HelpfulQuizSolution\HelpfulQuizCore\Core\DataAccess\Implimentation\QuizService.cs    Line: 32 

    Stack Trace: 

    [InvalidOperationException: The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?]
       Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\Creation\DynamicMethodConstructorStrategy.cs:209
       BuildUp_HelpfulQuizCore.Core.IPictureRepository(IBuilderContext ) +39
       Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs:37
       Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:43
       Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:511
    
    [ResolutionFailedException: Resolution of the dependency failed, type = "HelpfulQuizCore.Core.IPictureRepository", name = "(none)".
    Exception occurred while: while resolving.
    Exception is: InvalidOperationException - The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizCore.Core.IPictureRepository,(none)
    ]
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:515
       Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:173
       Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, ResolverOverride[] overrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainerExtensions.cs:504
       HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService..ctor() in c:\users\tim\documents\visual studio 2010\Projects\HelpfulQuizSolution\HelpfulQuizCore\Core\DataAccess\Implimentation\QuizService.cs:32
       BuildUp_HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService(IBuilderContext ) +110
       Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs:37
       Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:43
       Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:511
    
    [ResolutionFailedException: Resolution of the dependency failed, type = "HelpfulQuizCore.Core.DataAccess.Implimentation.IQuizService", name = "(none)".
    Exception occurred while: Calling constructor HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService().
    Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "HelpfulQuizCore.Core.IPictureRepository", name = "(none)".
    Exception occurred while: while resolving.
    Exception is: InvalidOperationException - The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizCore.Core.IPictureRepository,(none)
    
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService,(none) (mapped from HelpfulQuizCore.Core.DataAccess.Implimentation.IQuizService, (none))
      Calling constructor HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService()
    ]
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:515
       Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:173
       Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, ResolverOverride[] overrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainerExtensions.cs:504
       HelpfulQuizWeb.Quizzes.DataEntryPresenter..ctor() in c:\users\tim\documents\visual studio 2010\Projects\HelpfulQuizSolution\HelpfulQuizWeb\Quizzes\DataEntryPresenter.cs:27
       BuildUp_HelpfulQuizWeb.Quizzes.DataEntryPresenter(IBuilderContext ) +110
       Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs:37
       Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:43
       Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:511
    
    [ResolutionFailedException: Resolution of the dependency failed, type = "HelpfulQuizWeb.Quizzes.Interfaces.IDataEntryPresenter", name = "(none)".
    Exception occurred while: Calling constructor HelpfulQuizWeb.Quizzes.DataEntryPresenter().
    Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "HelpfulQuizCore.Core.DataAccess.Implimentation.IQuizService", name = "(none)".
    Exception occurred while: Calling constructor HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService().
    Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "HelpfulQuizCore.Core.IPictureRepository", name = "(none)".
    Exception occurred while: while resolving.
    Exception is: InvalidOperationException - The current type, HelpfulQuizCore.Core.IPictureRepository, is an interface and cannot be constructed. Are you missing a type mapping?
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizCore.Core.IPictureRepository,(none)
    
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService,(none) (mapped from HelpfulQuizCore.Core.DataAccess.Implimentation.IQuizService, (none))
      Calling constructor HelpfulQuizCore.Core.DataAccess.Implimentation.QuizService()
    
    -----------------------------------------------
    At the time of the exception, the container was:
    
      Resolving HelpfulQuizWeb.Quizzes.DataEntryPresenter,(none) (mapped from HelpfulQuizWeb.Quizzes.Interfaces.IDataEntryPresenter, (none))
      Calling constructor HelpfulQuizWeb.Quizzes.DataEntryPresenter()
    ]
       Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:515
       Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:173
       Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, ResolverOverride[] overrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainerExtensions.cs:504
       HelpfulQuizWeb.Quizzes.DataEntry.Page_Load(Object sender, EventArgs e) in c:\users\tim\documents\visual studio 2010\Projects\HelpfulQuizSolution\HelpfulQuizWeb\Quizzes\DataEntry.aspx.cs:34
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
       System.Web.UI.Control.OnLoad(EventArgs e) +91
       System.Web.UI.Control.LoadRecursive() +74
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

    ==========================================================================================================

    ==========================================================================================================

    Here is the app.config for the HelpfulQuiz core project.

     

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

     

        <configSections>

            <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

        </configSections> 

     

         <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">                 

             <alias alias="Core" type="HelpfulQuiz.Core" /> <!--When the computer sees the alias, it substitutes it for the type.-->  

             <alias alias="Core.Implimenation" type="HelpfulQuizSolution.HelpfulQuizCore.Core.Implimentation"  />

             <alias alias="ObjectContext" type="System.Data.Objects.ObjectContext, System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

             <alias alias="Entities" type="Entities"/>

             <assembly name="HelpfulQuizCore"/>

             <assembly name="HelpfulQuizCore_Tests"/>

             <assembly name="HelpfulQuizWeb"/>

             <assembly name="HelpfulQuizWeb_Tests"/>

             <assembly name="Entities"/>

             <assembly name="HQModel"/>

     

             <namespace name="HQModel"/>

             <namespace name="HQModel.Context"/>

             <namespace name="HelpfulQuizCore"/>

             <namespace name="HelpfulQuizCore.Core"/>

             <namespace name="HelpfulQuizCore.Core.DataAccess"/>

             <namespace name="HelpfulQuizCore.Core.DataAccess.Implimentation"/>     

             <namespace name="HelpfulQuizCore.Domain"/>

             <namespace name="HelpfulQuizCore.Implementation"/>       

             <namespace name="HelpfulQuizWeb.Quizzes.Interfaces"/>

             <namespace name="HelpfulQuizWeb.Quizzes"/>

             <namespace name="HelpfulQuizWeb"/>

     

     

                 <container>

                 <register type="Entities.Context" mapTo="Entities.Context">            

                 </register>

     

                 <register type="IConfiguration" mapTo="Configuration"/>              

     

                <register type="IEmail" mapTo="Email">

                     <constructor>

                         <param></param>

                     </constructor>

                 </register>

     

                <register type="IRedirector" mapTo="Redirector">

                    <constructor>

                        <param></param>

                    </constructor>

                </register>

     

                <register type="IWebContext" mapTo="WebContext" >

                     <constructor>

                         <param></param>

                     </constructor>

                 </register>

     

                <register type="HelpfulQuizCore.Core.IPictureRepository" mapTo="HelpfulQuizCore.DataAccess.Implimentation.PictureRepository">

                    <constructor>

                        <param></param>

                    </constructor>

                </register>

     

                <register type="IProductRepository" mapTo="ProductRepository"/>

                <register type="IProductScoreRepository" mapTo="ProductScoreRepository"/>

                <register type="IQuizItemRepository" mapTo="QuizItemRepository"/>

                <register type="ITagRepository" mapTo="TagRepository"/>

                <register type="IQuizService" mapTo="QuizService"/>

            </container>

     

        </unity>

     

    </configuration>

     

     

     

     

    Wednesday, April 27, 2011 8:13 PM

All replies

  • User-1757793930 posted

    Have you tried to add the Unity Per Execution lifetime Manager?

    I currently use in one of my projects, this allows me to use the Unity 2.0 in Win Forms, DLL's, Console Applications, Asp.Net & NVC Applications, there is some startup tasks involved but the idea is solid.

    The code base for this project is quite emense but we can give it a shot (not posting it here)

    The attached project contains the following.

    1. Business Logic Class containing
      1. The Unity Framework code,
      2. Sample calling classes that are also called internally (see ICalling & IWorker)
    2. Sample Applications
      1. Asp.Net Application
      2. WPF Application
      3. Console Application
      4. Winforms Applications
    3. All Unity Dependencies used.

    All the sample applications included have the same thing in common they all use the same business logic classes, they all initialize our dependency factories. You will also notice that the web application there is only one line in the Web.config, this line specifies the intialization of the Dependency Factory, also check out the Application_init in the global.asax.

    Additionally in the other projects (WPF, Console, Winforms) i am basically calling the same methods as the global.asax but doing it in the Application, Form, page etc load events.

    Explore the project and then please let me know if this helps you out.

    Project Location: http://unitytest.codeplex.com/

    Good luck

    Wednesday, April 27, 2011 10:33 PM
  • User-454803633 posted


    Thanks for your reply, I appreciate you trying to helping me.  I'm looking to use the Unity 2.0 container "as is" without adding 3rd party code.  Thank you very much, though, for taking the time to help me.

     

    Is it generally not possible to have Unity 2.0 running in different projects in the same solution?  Perhaps I've misunderstood, but the existence of your project suggests that is the case.  

    Wednesday, April 27, 2011 10:56 PM
  • User-1757793930 posted

    In the code example it may not be easy to spot initially, but how the Unity IoC is handled on a application wide variable.

     

    The class UnityPerExecutionContextLifetimeManager uses the Set, Get, Remove value methods to manage the Unity Provider through the Application context, and in this case through multiple projects. In fact it is the same instance, the instance is created by the DependencyResolverFactory in the application startup into one of the various container available to the running application (albeit Forms, Asp.Net Forms, WPF, Console etc)

    The project supplied doesnt use any 3rd party components ( other than Unity) just gives an easy reference on how to use the same instance across multiple projects of different types.

    Now to not get confused if you create an instace into the Asp.Net Web Forms, the same instance is not used in say the Console Application. They are sepereated per application instance.

    I would be happy to sort out this issue for you, let me review your initial question and see if i cant answer it using your configurations.

     

    Cheers, Nico

    Wednesday, April 27, 2011 11:53 PM
  • User-454803633 posted

    Ok, I studied the sample you sent for an hour or two.  This is a highly useful sample, thank you. I have, within my Asp.Net project, a IDefaultPresenter and a Presenter.cs class.  To register them, would I proceed as follows in the Global.asax.cs file?

     

      void Application_Start(object sender, EventArgs e)

            {

                // Code that runs on application startup

                //Initialize new dependency factory here, registering the IDefaultPresenter with the IPresenter class????

                //Initialize our IoC with our dependecy factory            

                IoC.InitializeWith(new DependencyResolverFactory()); 

            }

     

    The above solution doesn't seem like it would work, because the registrations are hard coded into the UnityDependencyResolver.cs class inside the BusinessLogic project, like so:

               container.RegisterType<Sample.IWorkerClass, Sample.WorkerClass>(new UnityPerExecutionContextLifetimeManager());

     

    How would I register classes from other projects?  

    In any event, I prefer to use the configuration files for Unity anyway to avoid the possiblility of circular references.  Am I correct to assume that I could register interfaces and classes using the config file in the BusinessLogic project? And is it necessary to place Unity in a wrapper to get it to work across multiple projects?  

    Thank you so much for spending your valuable time helping me.  This is my first large project, done solo, and I'm starting to wonder if I might just be better off without using an IOC container, as the complexity is overwhelming. :0

    Thursday, April 28, 2011 1:46 AM