2013-08-15 5 views
3

Я использую Umbraco 6.1 с UmbracoApiController, в который встроен IUnitOfWork, встроенный в его конструктор. Чтобы внедрить зависимости, я использую Unity, как и раньше, со стандартными проектами веб-API. Обычно я устанавливаю единство в Global.asax.cs. Как Umbraco не имеет этого я создал свой собственный обработчик UmbracoEvents, который наследуется от IApplicationEventHandler, и имеет методы:«Тип IUnitOfWork не имеет доступного конструктора» с Umbraco 6.1, UmbracoApiController (Web API) и Injection Dependency (Unity)

  1. OnApplicationInitialized
  2. OnApplicationStarting
  3. OnApplicationStarted
  4. ConfigureApi

В метод OnApplicationStarted. Я настроил свою базу данных EF, инициализатор db и т. д. и позвонил ConfigureApi для настройки Unity. Мои OnApplication работы и методы ConfigureApi выглядит следующим образом:

public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) 
    { 
     _applicationContext = applicationContext; 
     _umbracoApplication = umbracoApplication; 
     _contentService = ApplicationContext.Current.Services.ContentService; 
     this.ConfigureApi(GlobalConfiguration.Configuration); 
     Database.SetInitializer(null); 
     PropertySearchContext db = new PropertySearchContext(); 
     db.Database.Initialize(true); 
    } 

    private void ConfigureApi(HttpConfiguration config) 
    { 
     var unity = new UnityContainer(); 
     unity.RegisterType<PropertiesApiController>(); 
     unity.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager()); 
     config.DependencyResolver = new IoCContainer(unity); 
    } 

Мой контроллер код:

public class PropertiesApiController : UmbracoApiController 
{ 
    private readonly IUnitOfWork _unitOfWork; 

    public PropertiesApiController(IUnitOfWork unitOfWork) 
    { 
     if(null == unitOfWork) 
      throw new ArgumentNullException(); 
     _unitOfWork = unitOfWork; 
    } 

    public IEnumerable GetAllProperties() 
    { 
     return new[] {"Table", "Chair", "Desk", "Computer", "Beer fridge"}; 
    } 
} 

Мой Scope Контейнер/IoC Контейнер код: (по http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver)

public class ScopeContainer : IDependencyScope 
{ 
    protected IUnityContainer container; 

    public ScopeContainer(IUnityContainer container) 
    { 
     if (container == null) 
     { 
      throw new ArgumentNullException("container"); 
     } 
     this.container = container; 
    } 

    public object GetService(Type serviceType) 
    { 
     if (container.IsRegistered(serviceType)) 
     { 
      return container.Resolve(serviceType); 
     } 
     else 
     { 
      return null; 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     if (container.IsRegistered(serviceType)) 
     { 
      return container.ResolveAll(serviceType); 
     } 
     else 
     { 
      return new List<object>(); 
     } 
    } 

    public void Dispose() 
    { 
     container.Dispose(); 
    } 
} 

public class IoCContainer : ScopeContainer, IDependencyResolver 
{ 
    public IoCContainer(IUnityContainer container) 
     : base(container) 
    { 
    } 

    public IDependencyScope BeginScope() 
    { 
     var child = this.container.CreateChildContainer(); 
     return new ScopeContainer(child); 
    } 
} 

Мой IUnitOfWork код:

public interface IUnitOfWork : IDisposable 
{ 
    GenericRepository<Office> OfficeRepository { get; } 
    GenericRepository<Property> PropertyRepository { get; } 
    void Save(); 
    void Dispose(bool disposing); 
    void Dispose(); 
} 

Мои UnitOfWork реализация:

public class UnitOfWork : IUnitOfWork 
{ 
    private readonly PropertySearchContext _context = new PropertySearchContext(); 
    private GenericRepository<Office> _officeRepository; 
    private GenericRepository<Property> _propertyRepository; 

    public GenericRepository<Office> OfficeRepository 
    { 
     get 
     { 

      if (this._officeRepository == null) 
      { 
       this._officeRepository = new GenericRepository<Office>(_context); 
      } 
      return _officeRepository; 
     } 
    } 
    public GenericRepository<Property> PropertyRepository 
    { 
     get 
     { 

      if (this._propertyRepository == null) 
      { 
       this._propertyRepository = new GenericRepository<Property>(_context); 
      } 
      return _propertyRepository; 
     } 
    } 

    public void Save() 
    { 
     _context.SaveChanges(); 
    } 

    private bool disposed = false; 

    public virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       _context.Dispose(); 
      } 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

Я использовал единство/DI с контроллерами MVC4/WebAPI и эту реализацию UnitOfWork много раз до этого без проблем, так что я имею в виду, что это Umbraco специфичны.

Я также отладил приложение и убедился, что он попадает в OnApplicationStarted и что его параметры не равны нулю.

Метод GetAllProperties в контроллере только метод испытания, чтобы убедиться, что все работает нормально, однако, когда я пытаюсь получить доступ к этой акции я получаю ошибку:

«Тип IUnitOfWork не имеет доступный конструктор "

Есть ли у кого-нибудь опыт использования Umbraco 6.1 и UmbracoApiController с инъекцией зависимости/единством?

Кроме того, на несвязанной ноте, есть ли способ вернуть JSON вместо XML в действие? В Web API вы просто определяете форматтер в WebApi.config, но в Umbraco их нет.

Спасибо, Джастин

+0

Предложение 1: Что произойдет, если вы добавите конструктор по умолчанию в 'UnitOfWork' (который ничего не делает)? – Halvard

+0

Предложение 2: Вы видели этот вопрос? http://stackoverflow.com/questions/17898433/issue-resolving-dependencies-with-unity – Halvard

+0

Да, я это видел. в моем методе ConfigureApi я регистрирую тип IUnitOfWork/UnitOfWork с помощью HierarchicalLifetimeManager (который я всегда делаю в любом случае). Кроме того, я регистрирую тип, а не экземпляр. Возможно, мне нужно зарегистрировать экземпляр вместо этого для контроллера. Я на самом деле не пытался явно объявить пустой конструктор, как я думал, если бы вы его оставили, во время компиляции он все равно использовал его? Я попробую все равно и отчитаюсь :) – JustinMoser

ответ

1

В случае, если Вы не нашли решение проблемы? Скачать этот nuget package и сразу после создания вашего единства контейнер:

GlobalConfiguration.Configuration.DependencyResolver = 
    new Unity.WebApi.UnityDependencyResolver(Bootstrapper.Container); 

Обратите внимание на пространство имен, которое отличается от Unity.Mvc4.UnityDependencyResolver.