3

IUnitOfWork がコンストラクターに注入された UmbracoApiController で Umbraco 6.1 を使用しています。依存関係を注入するために、私は Unity を使用しています。これは、過去に標準の Web API プロジェクトで行ったのと同じです。通常は、Global.asax.cs に unity を設定します。Umbraco にはこれがないため、IApplicationEventHandler から継承し、次のメソッドを持つ独自の UmbracoEvents ハンドラーを作成しました。

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

OnApplicationStarted メソッドで、EF データベース、db 初期化子などをセットアップし、ConfigureApi を呼び出して Unity をセットアップします。私の OnApplication Started および 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"};
    }
}

私のスコープ コンテナー/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);
    }
}

MVC4/WebAPIコントローラーでunity/DIを使用し、このUnitOfWorkの実装を問題なく何度も使用したので、Umbraco固有のものだと思います。

また、アプリケーションをデバッグし、OnApplicationStarted にヒットし、そのパラメーターが null でないことを確認しました。

コントローラーの GetAllProperties メソッドは、すべて正常に動作していることを確認するための単なるテスト メソッドですが、このアクションにアクセスしようとすると、次のエラーが発生します。

「タイプ IUnitOfWork にはアクセス可能なコンストラクターがありません」

Umbraco 6.1 を使用した経験があり、それは依存性注入/Unity を使用した UmbracoApiController ですか?

また、無関係なメモとして、アクションで XML の代わりに JSON を返す方法はありますか? Web API では、WebApi.config でフォーマッタを定義するだけですが、Umbraco には何もありません。

ありがとう、ジャスティン

4

1 に答える 1

1

問題の解決策が見つからない場合は?Unity コンテナーをビルドした直後に、このnuget パッケージをダウンロードします。

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

とは異なる名前空間に注意してくださいUnity.Mvc4.UnityDependencyResolver

于 2014-08-18T13:01:50.973 に答える