在Domain Driven Design解决方案中构建IoC和ApplicationServiceRegistry测试

时间:2013-10-15 08:45:05

标签: unit-testing domain-driven-design code-organization

我将我的DDD应用程序拆分为以下项目:

  • MyApp.Domain
  • MyApp.Application
  • MyApp.Infrastructure
  • MyApp.Presentation

我正在使用IoC容器,目前具体的容器实例存在于Presentation层中(因为MVC 4 presentation-app本身可能使用IoC容器)。

域应用程序注册和解析位于基础架构层中,通过IDependencyResolver抽象,以允许IoC容器更改。

我希望明确定义域应用程序服务,以使表示代码非常清楚所调用的服务,即控制器操作“:

public ActionResult VpsServers(IApplicationServiceRegistry applicationServices)
{
    var service = applicationServices.ProductGroupService;
    var group = service.GetProductGroup("category-a");
    return View("ProductDetail", group);
}

基础设施代码

using MyApp.Application; // we reference the Application project from the Infrastructure project
using MyApp.Infrastructure.Repositories; // repositories are implemented in infrastructure

namespace MyApp.Infrastructure
{
    public interface IDependencyResolver
    {
        TService GetInstance<TService>()
            where TService : class;

        void Register<TConcrete>()
            where TConcrete : class;

        void Register<TService, TImplementation>()
            where TService : class
            where TImplementation : class, TService;

        void RegisterSingle<TService>(TService instance)
            where TService : class;

        void Verify();
    }

    public interface IApplicationServiceRegistry
    {
        ProductGroupService ProductGroupService { get; }
    }

    public class ApplicationServiceRegistry : IApplicationServiceRegistry
    {
        #region constructors
        public ApplicationServiceRegistry(IDependencyResolver iocContainer)
        {
            this.container = iocContainer;
            RegisterThis();
            RegisterTypes();
            container.Verify();
        }
        #endregion

        #region procedures
        protected void RegisterTypes()
        {
            this.container.Register<IProductRepository, InMemoryProductRepository>();
            this.container.Register<ICategoryRepository, InMemoryCategoryRepository>();
            this.container.Register<ProductGroupService>();
        }

        protected void RegisterThis()
        {
            this.container.RegisterSingle<IApplicationServiceRegistry>(this);
        }
        #endregion

        #region variables
        private readonly IDependencyResolver container;
        #endregion

        #region properties
        public ProductGroupService ProductGroupService
        {
            get { return this.container.GetInstance<ProductGroupService>(); }
        }
        #endregion
    }
}

Infrastructure.Test Code

namespace MyApp.Infrastructure.Test
{
    [TestClass]
    public class IocTest
    {
        [TestMethod]
        public void CanResolveService()
        {
            var container = new SimpleInjectorApplicationServiceAdapter();
            var applicationServiceRegistry = new ApplicationServiceRegistry(container);

            // the following line fails to compile, since we don't know about the ProductGroupService
            // since this lives in Application project, question is do we reference this Application project
            // or write a separate project for integration tests
            var service = applicationServiceRegistry.ProductGroupService;

            Assert.AreSame(applicationServiceRegistry, service); 
        }
    }
}

我正在编写MyApp.Infrastructure.Tests来测试IoC方面,但它抱怨它没有引用MyApp.Application项目ProductGroupService所在的项目。

我的问题是:

我知道我可以从MyApp.Application引用MyApp.Infrastructure.Test项目,但对我而言,这是代码气味。这是因为我实际上正在编写更多的集成测试(而不再是UnitTest),因为它跨越了多个项目和关注点?

还有其他更好的方法来构建这个或者我只是编写一个名为IntegrationTests的测试项目吗?

0 个答案:

没有答案