Unity中如何在注册时注入未知值

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

这里是Web API控制器

[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);
    }
}

请发布 MyFilter 的代码。在您的过滤器中,值 XXXXX 配置在哪里? - NightOwl888
你可以使用自定义类型转换器,并从配置中选择值。 - Amit Kumar Ghosh
在解析 ITestService 时,您可以注入 mystring 的值。 - Backs
您可以注册一个工厂,然后在工厂创建实际的 ITestService 时传递值。它还可以传递自己的类型,这样工厂就可以从该类型上的自定义属性获取值。 - Haukinger
2个回答

0

继续我上面的评论,这个示例展示了一种将过滤器值存储在属性中并恢复它以传递到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");
    }

0

在resolve方法中注入值:

container.RegisterType<ITestService,TestService>();
...
var service = container.Resolve<ITestService>(new ParameterOverride(@"mystring", new InjectionParameter(typeof(string), "XXXXX")));

那并没有解释我应该如何在哪里发送正确的值。 - TheBoubou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接