Я использую Umbraco 6.1 с UmbracoApiController, в который встроен IUnitOfWork, встроенный в его конструктор. Чтобы внедрить зависимости, я использую Unity, как и раньше, со стандартными проектами веб-API. Обычно я устанавливаю единство в Global.asax.cs. Как Umbraco не имеет этого я создал свой собственный обработчик UmbracoEvents, который наследуется от IApplicationEventHandler, и имеет методы:«Тип IUnitOfWork не имеет доступного конструктора» с Umbraco 6.1, UmbracoApiController (Web API) и Injection Dependency (Unity)
- OnApplicationInitialized
- OnApplicationStarting
- OnApplicationStarted
- 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 их нет.
Спасибо, Джастин
Предложение 1: Что произойдет, если вы добавите конструктор по умолчанию в 'UnitOfWork' (который ничего не делает)? – Halvard
Предложение 2: Вы видели этот вопрос? http://stackoverflow.com/questions/17898433/issue-resolving-dependencies-with-unity – Halvard
Да, я это видел. в моем методе ConfigureApi я регистрирую тип IUnitOfWork/UnitOfWork с помощью HierarchicalLifetimeManager (который я всегда делаю в любом случае). Кроме того, я регистрирую тип, а не экземпляр. Возможно, мне нужно зарегистрировать экземпляр вместо этого для контроллера. Я на самом деле не пытался явно объявить пустой конструктор, как я думал, если бы вы его оставили, во время компиляции он все равно использовал его? Я попробую все равно и отчитаюсь :) – JustinMoser