这里是 Unity 注册
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<ITestService,TestService>(new InjectionConstructor("XXXXX"));
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
这里是 webAPI 控制器
[MyFilter]
public class TestController : ApiController
{
private ITestService _testService;
public EmployeeController(ITestService testService)
{
_testService = testService;
}
}
我的测试类
public interface ITestService
{
string GetText();
}
public class TestService : ITestService
{
private string _mystring;
public TestService(string mystring)
{
_mystring = mystring;
}
public string GetText()
{
return _mystring;
}
}
问题:在构造函数中注入的值(此处硬编码为"XXXXX")仅在[MyFilter]
而不是之前知道,而不是在注册时知道。是否可以注入来自属性的值?
谢谢
更新1:我使用的解决方法是在会话中保存值"XXXXX"工作但不是很干净。
public class MyFilter: AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
try
{
HttpContext.Current.Session["MyData"] = "XXXXX";
return;
HandleUnauthorized(actionContext);
}
catch (Exception ex)
{
}
}
private void HandleUnauthorized(HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
在解析方法中注入值:
container.RegisterType<ITestService,TestService>();
...
var service = container.Resolve<ITestService>(new ParameterOverride(@"mystring", new InjectionParameter(typeof(string), "XXXXX")));
扩展我上面的评论,此示例展示了一种将过滤器值存储在属性中并恢复它以将其传递到TestService
的方法:
这假设每个TestController
将使用相同的过滤器(此处abc
),并且每个OtherTestController
将使用相同的其他过滤器(如,def
?也就是说,附加到类型的筛选器而不是实例。
class Program
{
static void Main( string[] args )
{
var unityContainer = new UnityContainer();
unityContainer.RegisterType<ITestServiceFactory, TestServiceFactory>();
var theController = unityContainer.Resolve<TestController>();
// theController._testService.FilterString is "abc"
}
}
[MyFilter("abc")]
public class TestController
{
private ITestService _testService;
public TestController( ITestServiceFactory testServiceFactory )
{
_testService = testServiceFactory.CreateTestService(this);
}
}
public class MyFilterAttribute : Attribute
{
public string FilterString
{
get;
}
public MyFilterAttribute( string filterString )
{
FilterString = filterString;
}
}
public interface ITestServiceFactory
{
ITestService CreateTestService( object owner );
}
public interface ITestService
{
string GetText();
}
internal class TestServiceFactory : ITestServiceFactory
{
public ITestService CreateTestService( object owner )
{
return new TestService( ((MyFilterAttribute)owner.GetType().GetCustomAttribute( typeof( MyFilterAttribute ) )).FilterString );
}
}
internal class TestService : ITestService
{
public TestService( string mystring )
{
_mystring = mystring;
}
public string GetText()
{
return _mystring;
}
private readonly string _mystring;
}
如果你不坚持这个属性,你可以简化它,直接在TestController
的构造函数中设置过滤器:
public TestController( ITestServiceFactory testServiceFactory )
{
_testService = testServiceFactory.CreateTestService("abc");
}