9

有什么办法可以用 Unity 3 解决这个问题吗?

我已尽一切可能绕过此消息错误,但我无法解决;我已经完成了我在谷歌搜索中看到的所有内容。

我几乎要放弃并尝试另一种 DI 解决方案。

我的配置文件:

<?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>

我的界面:

using Biblioteca.Transport;
using System.Linq;

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

我的具体课程:

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();
        }
    }
}

我的 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();
        }
    }
}

我的引导程序类:

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;
        }
    }
}

我的依赖项目静态类:

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>();
        }
    }
}

我在 MVC 4 项目上的 UI 模型类文件。我正在使用 4.5 框架。

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);
            }
        }
    }
}

我认为一切都是正确的。但是,我看不到这个 DI 工作,因为我在映射过程中遇到了一个错误,在我的 Bootstrapper 类 BuildUnityContainer 方法的下面一行:

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

错误是:

无法解析类型名称或别名 Biblioteca.Contracts.IManterCategoriaBO。请检查您的配置文件并验证此类型名称。

我已经仔细检查了我所有的课程,对我来说,他们没问题。或者它缺少什么?

4

6 回答 6

15

问题出在您的配置文件中。您将两个概念与一些不正确的语法混合在一起。

当您的节点包含自身无法找到的类型时, <assembly... />and<namespace ... />节点提供程序集和命名空间搜索顺序。<register ... />如果找不到类型,它将搜索 的所有组合[namespace].Type, [assembly]。这是错误所在:它不搜索Type, [assembly]. 如果定义了任何<namespace ... />节点,它不会尝试仅附加程序集。

因此,您的<register type="Biblioteca.Contracts.IManterCategoriaBO" mapTo="Biblioteca.Business.ManterCategoriaBO" />节点具有Biblioteca.Contracts.IManterCategoriaBO不包含程序集的类型,因此无法找到它。因此,它需要进行搜索。您确实指定了<namespace ... />节点,因此它将首先尝试Biblioteca.Biblioteca.Contracts.IManterCategoriaBO, Biblioteca. 注意重复的 Biblioteca 名称。

这是一个更正的配置文件。

<?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>
于 2013-09-07T08:14:43.623 回答
4

没有人说的一点信息是,我需要参考统一将使用的所有项目。

因此,在我的解决方案中,在我的 Biblioteca Web 项目中,有必要引用 Biblioteca.Business 和 Biblioteca.Contracts 才能通过统一寄存器而不会出现任何错误。我只引用了最后一个。

这太不可思议了,但那是我的问题!我认为统一能够使用我的 unity.config 文件中包含的所有路径进行某种反射。但是我错了。为了使 Unity 正常工作,有必要引用 unity.config 文件中的所有项目。如果我指向某个命名空间,则需要引用相关项目。

我已经解决了这个问题,但我不同意这种使统一工作的方法。但是,无论如何,它现在工作!

感谢泰勒,感谢您的支持。

于 2013-09-10T15:20:39.520 回答
2

如前一条评论所述,您可以在调用之前自己加载反射程序集UnityContainer.LoadConfiguration(...)。这是一种通用的方法。

只要确保可以按名称找到您的程序集。这可以通过将程序集放在应用程序的 bin 目录中来完成。或者<probing>为您的应用配置添加路径。或者将它们添加到全局程序集缓存 (GAC),但我不推荐这样做。

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);
        }
    }
}
于 2013-09-19T02:46:25.130 回答
1

我只是花了我一天的大部分时间来解决这个错误。

在我的情况下,配置没有错误,但事实证明,其中一个包含具体类型的程序集依赖于另一个它找不到的程序集。

不幸的是,Unity 没有暗示加载程序集的任何问题。事实上,程序集显示在 Visual Studio 调试器的“模块”窗口中。仍然无法加载类型。

于 2015-06-03T21:57:45.070 回答
1

我也收到了此错误消息,但发现了另一组原因:

  1. 我正在使用一个未正确部署目标程序集所需的某些 dll 的 WiX 安装程序(在此示例中,它将是 Biblioteca.Business 的依赖项)。所以仔细检查一下。
  2. 然后我只有在发布模式下运行时才收到错误消息,调试模式工作正常。原来目标 mapTo 类没有用“public”属性标记。出于某种原因,这在调试模式下无关紧要,但在发布模式下却是一个障碍。

希望对某人有所帮助,因为它阻止了我两天。

于 2016-11-29T20:39:32.123 回答
1

如果您来自谷歌,最简单的让它工作的方法是删除<alias>and<namespace>东西并执行以下操作。

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

...MyApp项目属性 - > 应用程序中的程序集名称在哪里。

于 2016-05-23T15:31:48.023 回答