Unity 3 and Error “The type name or alias ”xxxxx“ could not be resolved. Please check your configuration file and verify this type name.”

假装没事ソ 提交于 2019-11-29 19:08:17

问题


Is there any way to resolve this problem with Unity 3 ?

I have made all that is possible to bypass this message error, but I can't resolve; I have already did everything I've seen in googles searches.

I am almost giving up and trying another DI solution.

My configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly name="Biblioteca" />
    <assembly name="Biblioteca.Contracts" />
    <assembly name="Biblioteca.Business" />
    <namespace name="Biblioteca" />
    <namespace name="Biblioteca.Contracts" />
    <namespace name="Biblioteca.Business" />
      <container>
        <register type="Biblioteca.Contracts.IManterCategoriaBO" mapTo="Biblioteca.Business.ManterCategoriaBO" />
      </container>
  </unity>
</configuration>

My interface:

using Biblioteca.Transport;
using System.Linq;

namespace Biblioteca.Contracts
{
    public interface IManterCategoriaBO
    {
        IQueryable<CategoriaDTO> GetAll();
        CategoriaDTO GetById(int id);
        void Insert(CategoriaDTO dto);
    }
}

My concrete class:

using Biblioteca.Contracts;
using Biblioteca.Transport;
using Biblioteca.Data;
using System;
using System.Linq;

namespace Biblioteca.Business
{
    public class ManterCategoriaBO : IManterCategoriaBO
    {
        public CategoriaDTO GetById(int id)
        {
            CategoriaDTO dto = new CategoriaDTO();
            ManterCategoriaDO categoriaDO = new ManterCategoriaDO();

            dto = categoriaDO.GetById(1);

            return dto;
        }

        public IQueryable<CategoriaDTO> GetAll()
        {
            throw new NotImplementedException();
        }

        public void Insert(CategoriaDTO dto)
        {
            throw new NotImplementedException();
        }
    }
}

My Global.asax:

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Biblioteca.Dependency;

namespace Biblioteca
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //Below is a static variable to take the unity container
            //which is on a dependency project
            Global.Container = Bootstrapper.Initialise();
        }
    }
}

My Bootstrapper class:

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using System.Web.Mvc;
using Unity.Mvc4;

namespace Biblioteca
{
    public static class Bootstrapper
    {
        public static IUnityContainer Initialise()
        {
            var container = BuildUnityContainer();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            return container;
        }

        private static IUnityContainer BuildUnityContainer()
        {
            string path = ConfigurationManager.AppSettings["UnityConfigFilePath"].ToString();

            var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = path + "\\Unity.config" };

            System.Configuration.Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");

            //*** this line is firing the error !!! ****
            var container = new UnityContainer().LoadConfiguration(unitySection);

            return container;
        }
    }
}

My Dependency project static class:

using Microsoft.Practices.Unity;

namespace Biblioteca.Dependency
{
    public static class Global
    {
        public static IUnityContainer Container = null;

        public static T Resolve<T>()
        {
            return Container.Resolve<T>();
        }
    }
}

My UI model class file on MVC 4 project. I am using 4.5 framework.

using Biblioteca.Contracts;
using Biblioteca.Dependency;

namespace Biblioteca.Models
{
    public class LivroModel
    {
        public void GetAll()
        {
            if (Global.Container != null)
            {
                var categoriaBO = Global.Resolve<IManterCategoriaBO>();
                categoriaBO.GetById(1);
            }
        }
    }
}

I think everything is in the right way. But, I can´t see this DI works cause I got an error just in the mapping process, in line below on my Bootstrapper class, BuildUnityContainer method:

var container = new UnityContainer().LoadConfiguration(unitySection);

The error is:

The type name or alias Biblioteca.Contracts.IManterCategoriaBO could not be resolved. Please check your configuration file and verify this type name.

I have double checked all my classes and for me, they are ok. Or is it missing anything ?


回答1:


The problem is in you config file. You are mixing two concepts with some incorrect syntax.

The <assembly... /> and <namespace ... /> nodes provide an assembly and namespace search order when your <register ... /> node contains a type that cannot be found by itself. If a type cannot be found, it searches through all combinations of [namespace].Type, [assembly]. Here's where the error is: it does NOT search for Type, [assembly]. If any <namespace ... /> nodes are defined, it does NOT try appending only the assembly.

So your <register type="Biblioteca.Contracts.IManterCategoriaBO" mapTo="Biblioteca.Business.ManterCategoriaBO" /> node has the type Biblioteca.Contracts.IManterCategoriaBO which does not contain the assembly, so it cannot be found. Therefore, it needs to do a search. You did specify <namespace ... /> nodes, so it will first try Biblioteca.Biblioteca.Contracts.IManterCategoriaBO, Biblioteca. Notice the duplicate Biblioteca name.

Here's a corrected config file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly name="Biblioteca" />
    <assembly name="Biblioteca.Contracts" />
    <assembly name="Biblioteca.Business" />
    <namespace name="Biblioteca" />
    <namespace name="Biblioteca.Contracts" />
    <namespace name="Biblioteca.Business" />
    <container>
      <register type="IManterCategoriaBO" mapTo="ManterCategoriaBO" />
      <!-- Or this works -->
      <!--<register type="Biblioteca.Contracts.IManterCategoriaBO, Biblioteca" mapTo="Biblioteca.Business.ManterCategoriaBO, Biblioteca" />-->
    </container>
  </unity>
</configuration>



回答2:


A little information that nobody nowhere says is that I need to make reference to all the projects that will be used by unity.

So, in my solution, inside my Biblioteca web project, it was necessary to reference Biblioteca.Business and Biblioteca.Contracts to be able to pass throught the unity register without any error. I was referencing only the last one.

It´s is incredible, but that was my problem !!! I´ve thought the unity was able to make some kind of refletion using all the paths included inside my unity.config file. But I was wrong. To make Unity works, its necessary to reference all the projects that are inside the unity.config file. If I point to some namespace, the related project need to be referenced.

I have already resolved the problem, but I do not agree with this approach to make unity works. But, anyway, its working now !!!

Thanks any way Tyler, for your support.




回答3:


As stated in the previous comment, you could do the reflection assembly load yourself before calling UnityContainer.LoadConfiguration(...). Here's a generic way to do so.

Just be sure your assemblies can be found by name. This can be done by placing the assembly in your application's bin directory. Or add a <probing> path to your app config. Or add them to the Global Assembly Cache (GAC), but I don't recommend this.

private static void LoadDependencyAssemblies() 
{
    UnityConfigurationSection section = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
    if (section == null)
    {
        throw new ConfigurationErrorsException("Unable to locate Unity configuration section.");
    }

    foreach (string assemblyName in section.Assemblies.Select(element => element.Name))
    {
        try
        {
            Assembly.Load(assemblyName);
        }
        catch (Exception ex)
        {
            throw new ConfigurationErrorsException("Unable to load required assembly specified in Unity configuration section.  Assembly: " + assembly, ex);
        }
    }
}



回答4:


I was receiving this error message as well but found another set of causes :

  1. I am using a WiX installer which was not properly deploying some of the dlls required for the target assembly (In this example it would be dependencies of the Biblioteca.Business). So double check that.
  2. I was then getting the error message only when running in release mode, debug mode worked fine. Turns out the target mapTo class was not marked with "public" attribute. For some reason this did not matter in debug mode but is a blocker in release mode.

Hope that helps someone since it blocked me for two days.




回答5:


I just spend a good portion of my day troubleshooting this error.

In my case there was no error in the configuration, but it turned out that one of the assemblies holding the concrete types was depending on another assembly that it could not find.

Unfortunately, Unity did not hint at any issues loading the assembly. In fact, the assembly showed up in the Modules window in the Visual Studio Debugger. Still the type could not be loaded.




回答6:


If you're here from google, the simplest way to get it working is to remove the <alias> and <namespace> stuff and do the following.

<container>
  <register type="MyApp.Repositories.IUserRepository, MyApp" mapTo="MyApp.Repositories.UserRepository, MyApp" />
</container>

...where MyApp is your Assembly Name from project Properties -> Application.



来源:https://stackoverflow.com/questions/18668240/unity-3-and-error-the-type-name-or-alias-xxxxx-could-not-be-resolved-please

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!