Unity DI N层架构——寄存器类型业务>数据

Unity DI N-tier architecture - register types business > data

我正在使用最新版本的 Unity(3.5.1405-prerelease)来注入依赖项(三层架构)。

Project.Web

应用层,MVC。

App_Start:

public static class UnityWebActivator
{
    public static void Start() 
    {
        var container = UnityConfig.GetConfiguredContainer();

        FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
        FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }

    public static void Shutdown()
    {
        var container = UnityConfig.GetConfiguredContainer();
        container.Dispose();
    }
}

public class UnityConfig
{
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }
    #endregion

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<IAccountService, AccountService>();
        container.RegisterType<IAdministrationService, AdministrationService>();
    }
}

Project.Business

业务层,class库。包含服务。

Project.Data

数据层,class库。包含存储库。

Question

How do I register types for my data layer? Currently it's only registrating Application layer -> Business layer. I dont want to register business layer -> data layer within my application layer.

更新 1 - 示例

这是我想从数据库中检索用户 ID 的示例。

应用层:

public class HomeController : Controller
{
    private readonly IUserService _userService;

    public HomeController(IUserService userService)
    {
        _userService = userService;
    }

    [HttpGet]
    public ActionResult GetUserID()
    {
        int userID = _userService.GetUserIDGuest("test@gmail.com");

        return View(userID);
    }
}

服务层:

public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;

        public UserService(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        public int GetUserIDGuest(string email)
        {
            return _userRepository.GetUserIDGuest(email);
        }
}

数据层:

    public abstract class RepositoryBase
    {
        protected readonly DataLayer DB;
        protected readonly CloudStorageServices Storage;

        protected RepositoryBase(DataLayer db, CloudStorageServices storage)
        {
            DB = db;
            Storage = storage;
        }
    }

public class UserRepository : RepositoryBase, IUserRepository
{
    public UserRepository(DataLayer db, CloudStorageServices storage) : base(db, storage) { }

    public int GetUserIDGuest(string email)
    {
        return DB.User.Where(m => m.Email == email.ToLower().Trim() && m is Guest).Select(o => o.UserID).SingleOrDefault();
    }
}

在我看来,从您提供的示例来看,服务层是一组简单的 classes,它们将与您的 ASP.NET 站点(即它不是在自己的进程中运行的完整应用程序。

也就是说你的服务层本身并没有构成一个应用

您应该在 ASP.NET 的 Composition Root 注册所有内容(例如 IUserServiceIUserRepositoryDataLayerCloudStorageServices)应用程序,即使这意味着您的应用程序将引用所有其他 class 库。

这很好,应用程序本身需要引用所有内容,这是您拼凑拼图的地方。

class 库不应引用所有内容,而应仅引用包含抽象或它们所依赖的其他类型的其他 class 库。

引用我引用的文章(Composition Root):

Only applications should have Composition Roots. Libraries and frameworks shouldn't.