2013-09-06 4 views
8

Czy istnieje sposób na rozwiązanie tego problemu z Unity 3 ???Unity 3 and Error "Nie można rozpoznać nazwy lub aliasu" xxxxx ". Sprawdź plik konfiguracyjny i zweryfikuj nazwę tego typu."

Zrobiłem wszystko, co możliwe, aby ominąć ten błąd wiadomości, ale nie mogę rozwiązać ... Mam 2 dni próbując rozwiązać i już zrobiłem wszystko, co widziałem w wyszukiwaniach google.

Prawie rezygnuję i próbuję innego rozwiązania DI. Proszę, każda pomoc będzie dobrze ...

Mój plik konfiguracyjny:

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

Mój interfejs:

using Biblioteca.Transport; 
using System.Linq; 

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

Moja klasa betonu:

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 inicjującego klasa:

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

Mój projekt Zależność statyczne klasy:

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

Moja UI modelu MVC plik klasy na 4 projektu. Używam 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); 
      } 
     } 
    } 
} 

Myślę, że wszystko jest we właściwy sposób. Ale nie widzę tego DI działa, ponieważ dostałem błąd tylko w procesie mapowania, w linii poniżej na mojej klasie Bootstrapper, metoda BuildUnityContainer:

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

Błąd jest:

Nazwa typu lub pseudonim Biblioteca.Contracts.IManterCategoriaBO mógłby nie zostać rozwiązany. Sprawdź swój plik konfiguracyjny i zweryfikuj nazwę tego typu: .

Mam podwójnie sprawdzone wszystkie moje klasy i dla mnie są one w porządku. A może czegoś brakuje?

Potrzebuję pomocy, bo mam mało czasu, aby zadbać o to ....

Pozdrowienia, Marcelo.

+0

Czy wasz zespół ma silną nazwę? Zauważyłem, że czasami muszę użyć w pełni kwalifikowanej nazwy typu (z kluczem publicznym), aby załadować ją poprzez Unity config. Nawet w przypadku nieskonfigurowanych zestawów musiałem dodać część złożoną do nazwy typu. –

Odpowiedz

11

Problem dotyczy pliku konfiguracyjnego. Łączymy dwie koncepcje z niepoprawną składnią.

Węzły <assembly... /> i <namespace ... /> zapewniają złożenie i kolejność wyszukiwania przestrzeni nazw, gdy węzeł <register ... /> zawiera typ, którego nie można samodzielnie znaleźć. Jeśli nie można znaleźć typu, przeszukuje wszystkie kombinacje [namespace].Type, [assembly]. Oto gdzie jest błąd: NIE wyszukuje Type, [assembly]. Jeśli zdefiniowane są jakiekolwiek węzły <namespace ... />, to NIE próbuje on dołączać tylko zespołu.

Twój węzeł <register type="Biblioteca.Contracts.IManterCategoriaBO" mapTo="Biblioteca.Business.ManterCategoriaBO" /> ma typ Biblioteca.Contracts.IManterCategoriaBO, który nie zawiera zespołu, więc nie można go znaleźć. Dlatego musi wykonać wyszukiwanie. Podałeś węzły <namespace ... />, więc najpierw spróbujesz Biblioteca.Biblioteca.Contracts.IManterCategoriaBO, Biblioteca. Zwróć uwagę na zduplikowaną nazwę Biblioteca.

Oto poprawiony plik konfiguracyjny.

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

Dokumentacja dotycząca tej funkcji znajduje się w [tym pliku pomocy] (https://unity.codeplex.com/downloads/get/669364) w sekcji Konfigurowanie jedności -> Konfiguracja w czasie projektowania -> Określanie typów w pliku konfiguracyjnym -> Automatyczne wyszukiwanie typu. – TylerOhlsen

+0

Cześć Tyler, nie ma mowy ... Zrobiłem to, co powiedziałeś. Ale problem utrzymuje się. – Olivertech

+0

Udało mi się odtworzyć błąd i naprawić go tym, co tu powiedziałem. Nie wiem, dlaczego to by nie działało dla ciebie. Nie działa również z kwalifikowaną nazwą zestawu? TylerOhlsen

4

Mała informacja, której nikt nigdzie nie mówi, polega na tym, że muszę odnieść się do wszystkich projektów, które będą używane przez jedność.

Tak więc, w moim rozwiązaniu, w moim projekcie internetowym Biblioteca konieczne było odwołanie się do Biblioteca.Business i Biblioteca.Contracts, aby móc bez problemu przechodzić przez rejestr jedności. Odniosłem się tylko do ostatniego.

To niesamowite, ale to był mój problem !!! Sądziłem, że jedność była w stanie dokonać jakiegoś refletu używając wszystkich ścieżek zawartych w moim pliku unity.config. Ale byłem w błędzie. Aby Unity działało, konieczne jest odwołanie się do wszystkich projektów znajdujących się w pliku unity.config. Jeśli wskażę pewien obszar nazw, należy odwołać się do powiązanego projektu.

Rozwiązałem już problem, ale nie zgadzam się z tym podejściem, aby uczynić jedność. Ale w każdym razie teraz działa!

Dzięki za wszelką pomoc Tyler za wsparcie.

+5

Nie powinieneś używać twardego odniesienia do innych zgromadzeń. Wystarczy je załadować do bieżącej domeny aplikacji. Jeśli chcesz, aby był bardziej dynamiczny, możesz napisać swój własny kod, który używa refleksji do załadowania wymaganych zestawów do domeny aplikacji, wywołując wywołanie 'Assembly.Load (" Biblioteca.Business ")' i 'Assembly.Load (" Biblioteca.Contracts ")' przed wywołaniem 'UnityContainer.LoadConfiguration (...)'. – TylerOhlsen

+1

Odwoływanie nie jest wymagane, jeśli ręcznie skopiujesz biblioteki DLL do folderu bin, który również będzie działał. Przykładem jest posiadanie jednej ogólnej aplikacji, która wypytuje za pomocą dowolnej implementacji, którą mu podaję, tj. Umieszczam odpowiednią bibliotekę DLL w katalogu bin i konfiguruję ją tak, aby korzystała z tej biblioteki DLL. Nie ma potrzeby ładowania biblioteki DLL w kodzie, sekcja Unity config (assembly) to robi. Jedynym wymaganym kodem jest utworzenie nowego UnityContainer, wywołanie LoadConfiguration, a następnie rozwiązanie interfejsu. –

2

Jak wspomniano w poprzednim komentarzu, można samemu wykonać montaż zespołu odbicia przed wywołaniem UnityContainer.LoadConfiguration(...). Oto ogólny sposób, aby to zrobić.

Po prostu upewnij się, że twoje złoenia można znaleźć po imieniu. Można to zrobić, umieszczając zestaw w katalogu bin aplikacji. Lub dodaj ścieżkę <probing> do konfiguracji aplikacji. Lub dodaj je do Global Assembly Cache (GAC), ale nie polecam tego.

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

Potrzebuję załadować zespół projektu w moim rozwiązaniu, który został umieszczony w folderze /Main/Biblioteki z kodu innego projektu rozwiązania, umieszczonego w /Shop? Czy potrafisz opisać w swojej odpowiedzi, jak użyć do tego celu ? –

+0

Zakładam, że masz na myśli zamiast . Powinienem móc użyć czegoś takiego: TylerOhlsen

0

Po prostu spędzam dużą część dnia, rozwiązując ten problem.

W moim przypadku nie wystąpił błąd w konfiguracji, ale okazało się, że jeden z zespołów z konkretnymi typami był zależny od innego zespołu, którego nie mógł znaleźć.

Niestety, Unity nie wskazało żadnych problemów podczas ładowania zespołu. W rzeczywistości zestaw pojawił się w oknie modułów w Visual Studio Debugger. Nadal nie można załadować typu.

0

Jeśli jesteś tutaj z google, najprostszym sposobem, aby go uruchomić, jest usunięcie rzeczy: <alias> i i wykonanie następujących czynności.

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

... gdzie MyApp to nazwa Zgromadzenie od projektu Właściwości -> Application.

1

ja otrzymywał ten komunikat o błędzie, jak dobrze, ale znaleźć inny zestaw przyczyn:

  1. używam Instalator WiX, który nie został prawidłowo wdrażana niektórych bibliotek DLL potrzebnych do montażu docelowego (w tym przykładzie byłyby zależnościami Biblioteca.Business). Więc sprawdź to jeszcze raz.
  2. Otrzymałem komunikat o błędzie tylko podczas uruchamiania w trybie zwolnienia, tryb debugowania działał poprawnie. Wyłącza mapę targetDo klasy nie został oznaczony atrybutem "public". Z jakiegoś powodu nie miało to znaczenia w trybie debugowania, ale jest blokerem w trybie zwolnienia.

Mam nadzieję, że pomaga komuś, ponieważ zablokował mnie na dwa dni.

Powiązane problemy