有没有办法解决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();
}
}
}
我的Bootstrapper课程:
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项目静态类:
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可以 没有解决。请检查您的配置文件并验证这一点 类型名称。
我已经仔细检查了所有课程,对我来说,他们还可以。或者它缺少什么?
答案 0 :(得分:14)
问题在于您的配置文件。您正在使用一些不正确的语法混合两个概念。
当<assembly... />
节点包含自身无法找到的类型时,<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>
答案 1 :(得分:4)
没有人说的一点信息是我需要参考统一使用的所有项目。
所以,在我的解决方案中,在我的Biblioteca网络项目中,有必要引用Biblioteca.Business和Biblioteca.Contracts以便能够通过统一寄存器而没有任何错误。我只引用了最后一个。
这太不可思议了,但那是我的问题!!!我认为团结能够使用unity.config文件中包含的所有路径进行某种反映。但是我错了。要使Unity工作,必须引用unity.config文件中的所有项目。如果我指向某个命名空间,则需要引用相关项目。
我已经解决了这个问题,但我不同意这种使团结合作的方法。但是,无论如何,它现在正在工作!!!
谢谢泰勒的任何支持。
答案 2 :(得分: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);
}
}
}
答案 3 :(得分:1)
我也收到了此错误消息,但发现了另一组原因:
希望帮助某人,因为它阻止了我两天。
答案 4 :(得分:0)
我只花了很多时间来解决此错误。
在我的情况下,配置中没有错误,但事实证明,其中一个包含具体类型的程序集依赖于它找不到的另一个程序集。
不幸的是,Unity没有暗示加载程序集的任何问题。实际上,程序集显示在Visual Studio调试器的“模块”窗口中。仍然没有加载类型。
答案 5 :(得分:0)
如果您来自谷歌,最简单的方法是删除<alias>
和<namespace>
内容并执行以下操作。
<container>
<register type="MyApp.Repositories.IUserRepository, MyApp" mapTo="MyApp.Repositories.UserRepository, MyApp" />
</container>
...其中MyApp
是项目属性中的程序集名称 - &gt;应用