gpt4 book ai didi

c# - Autofac:如何将 IPrincipal 注入(inject) Repository 层

转载 作者:太空宇宙 更新时间:2023-11-03 15:48:11 26 4
gpt4 key购买 nike

我正在设计一个使用存储层/服务层/表示层的 n 层应用程序,使用 c#.net web api 和 Autofac DI 容器。这是我的困境。我正在尝试对我的 web api Controller 进行单元测试,但我的存储库对 IPrincipal 具有属性依赖性,我想将其属性注入(inject)到我的存储库层中。我想创建一个 MockUser(IPrincipal) 并将此对象注入(inject)我的存储库。这是我当前的层次结构,我的 Controller 是用服务对象注入(inject)的构造函数,我的服务对象是用我的存储库对象注入(inject)的构造函数。这部分似乎有效。但出于某种原因,每次我运行测试时,我的 Principal 属性都是空的。请查看下面的代码,让我知道我做错了什么:

Repository Base Class:

protected IPrincipal Principal
{
get { return _principal; }
}


Autofac Config Static Method

public class AutofacConfig
{
public static IContainer ConfigContainer()
{
var _builder = new ContainerBuilder();

UserPrincipal principal = MemberFactory.GetTestUser();



var _config = new HttpConfiguration();
_builder.RegisterControllers(typeof(BillingController).Assembly);
_builder.RegisterWebApiModelBinders(typeof(BillingController).Assembly);
_builder.RegisterApiControllers(typeof(BillingController).Assembly);
_builder.RegisterModelBinders(typeof(BillingController).Assembly);
_builder.RegisterModelBinderProvider();
_builder.RegisterModule(new AutofacWebTypesModule());

_builder.RegisterSource(new ViewRegistrationSource());
_builder.RegisterFilterProvider();
_builder.RegisterWebApiFilterProvider(_config);

//_builder.Register(x => principal).As<IPrincipal>().PropertiesAutowired();
_builder.RegisterType<BillingRepository>().As<IBillingRepository>().PropertiesAutowired();
_builder.RegisterType<UserPrincipal>().As<IPrincipal>().PropertiesAutowired();
_builder.RegisterType<GroupRepository>().As<IGroupRepository>().PropertiesAutowired();
_builder.RegisterType<BillingService>().As<IBillingService>().PropertiesAutowired();
_builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
_builder.Register(c => principal).As<IPrincipal>();

var _container = _builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(_container));

// Create the depenedency resolver.
var resolver = new AutofacWebApiDependencyResolver(_container);

// Configure Web API with the dependency resolver.
_config.DependencyResolver = resolver;

return _container;
}
}

Test Controller (Get Method)

[TestClass]
public class BillingControllerTest
{
[TestMethod]
public async Task Get()
{
var _container = AutofacConfig.ConfigContainer();

var _controller = _container.Resolve<BillingController>();

var _bodyCompRecords = await _controller.GetMyOutstandingBills(1, 10);

Assert.IsNull(_bodyCompRecords);
Assert.IsNull(_bodyCompRecords.BillingList);
Assert.IsNull(_bodyCompRecords.CurrentPage);
Assert.IsTrue(_bodyCompRecords.BillingList.Count > 0);
}
}

最佳答案

您是否尝试为此属性添加保护集?我不确定 autofac,但也许你应该用一些属性来装饰这个属性,让 autoFac 知道这是一个可注入(inject)的属性。

另一方面,.Net 应用程序中的所有线程都有一个主体。您可以在 Thread.CurrentPrincipal 静态属性上获取/设置它。您可以尝试设置自定义委托(delegate)人并使您的属性(property)产生它。

在单元测试的设置中,您可以定义它,例如:

void Setup()
{
IPrincipal principal = new GenericPrincipal(new GenericIdentity("userName"), new string[] { "role1", "role2" });
Thread.CurrentPrincipal = principal;
}

在您的存储库中,您可以有一个属性来公开它,

protected IPrincipal Principal 
{
get { return Thread.CurrentPrincipal; }
}

在 Web 应用程序 (asp.net webforms/mvc/web api) 中,您可以使用 HttpContext.Current.User 静态属性,因此,只需调用:

HttpContext.Current.User = principal;

作为一个好习惯,您可以同时设置 HttpContext.Current.UserThread.CurrentPrincipal。请记住,Web API 是无状态的,因此,实现一个 http 模块以从 http header 读取参数并将主体设置为您的应用程序。我不确定这是不是你的情况,但是this article显示如何执行此操作。

http://www.asp.net/web-api/overview/security/basic-authentication

关于c# - Autofac:如何将 IPrincipal 注入(inject) Repository 层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27154862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com