在向 Unity 注册时注入未知值



这里是 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");
    }

最新更新