在asp核心中通过DI初始化带有参数的对象

时间:2017-05-17 06:40:09

标签: c# dependency-injection asp.net-core

我在asp核心应用程序中使用了常见的DI。

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork));//DAL
    services.AddScoped(typeof(IUpService), typeof(UpService));//BLL
    ...
}

控制器通过DI获取UpService:

public BaseController(IUpService upService)
{
    _upService = upService;
}

然后BLL(upservice)获得unitofwork实例:

public UpService(IUnitOfWork unitOfWork)
{
    _unitOfWork = unitOfWork;
}

在基础控制器中,我有属性CurrentUser

public User CurrentUser
{
    get
    {
        User user = null;
        var tokenCookie = HttpContext.Request.Headers.FirstOrDefault(c => c.Key == "token");
        if (!string.IsNullOrEmpty(tokenCookie.Value) && tokenCookie.Value != "undefined")
        {
            user = _upService.GetUserById(new Guid(tokenCookie.Value));
        }
        return user;
    }
}

我需要的是将CurrentUser传递给BL图层(到UpService)。如何在asp核心中通过DI实现它?

UPD: 这是UpService的一部分,我需要当前的用户。

public class UpService : IUpService
{
    private IUnitOfWork _unitOfWork;

    public User CurrentUser { get; set; }


    public UpService(IUnitOfWork unitOfWork, IUserContext userContext)
    {
        _unitOfWork = unitOfWork;
        //CurrentUser = userContext.CurrentUser;
    }


    public void Update(Document doc)
        {
//here complex BL and then...
                Document local;
                var entity = _unitOfWork.DocumentsRepository.GetByID(doc.Id);
                if (entity != null && HasChanges(local, entity))
                {
                    entity.ChangedById = CurrentUser.Id;
                    _unitOfWork.Save();
                }
        }

        public User GetUserById(Guid id)
        {
            return _unitOfWork.UserRepository.GetByID(id);
        }

...

1 个答案:

答案 0 :(得分:1)

您应该将CurrentUser提取到抽象中,让我们将其称为IUserContext。这种抽象可以在您的核心层实现。这样BL和DAL就可以访问它。作为Web应用程序的一部分,您可以创建适应ASP.NET Core的实现,并且基本上包含CurrentUser属性所具有的逻辑。例如:

public interface IUserContext
{
    User CurrentUser { get; }
}

适配器可以如下所示:

public class AspNetUserContextAdapter : IUserContext
{
    private readonly IHttpContextAccessor _accessor;
    private readonly IUpService _upService;

    public AspNetUserContextAdapter(IHttpContextAccessor accessor, IUpService _upService) { 
        _accessor = accessor;
        _upService = upService;
    }

    public User CurrentUser
    {
        get
        {
            var context = _accessor.HttpContext;
            var tokenCookie = context.Request.Headers.FirstOrDefault(c => c.Key == "token");
            return !string.IsNullOrEmpty(tokenCookie.Value) && tokenCookie.Value != "undefined"
                ? _upService.GetUserById(new Guid(tokenCookie.Value))
                :  null;
        }
    }
}

此适配器可以照常注册:

services.AddTransient<IUserContext, AspNetUserContextAdapter>();

最重要的是,您可能需要注册ASP.NET Core&#39; IHttpContextAccessor,因为(在旧版本的ASP.NET Core中)默认情况下未注册:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();