Dependency injection 我可以为Castle Windsor中的代理类型定义自定义属性吗

Dependency injection 我可以为Castle Windsor中的代理类型定义自定义属性吗,dependency-injection,inversion-of-control,castle-windsor,castle,castle-dynamicproxy,Dependency Injection,Inversion Of Control,Castle Windsor,Castle,Castle Dynamicproxy,我有一个类,我用Castle Dynamic proxy代理它。我想向代理方法添加一些自定义属性(在代理类中未定义)。这可能吗 我之所以要这样做,是因为我想为我的应用程序的服务层生成ASP.NET Web API层。我使用代理服务(从ApiController和其他IMyService接口继承),它工作得很好,但我想向这个新创建的动态类添加特定于WebAPI的属性,这样WebAPI框架就可以读取它们 编辑: 如果有人想知道我到底想要什么,我想详细解释一下 public interface IMy

我有一个类,我用Castle Dynamic proxy代理它。我想向代理方法添加一些自定义属性(在代理类中未定义)。这可能吗

我之所以要这样做,是因为我想为我的应用程序的服务层生成ASP.NET Web API层。我使用代理服务(从ApiController和其他IMyService接口继承),它工作得很好,但我想向这个新创建的动态类添加特定于WebAPI的属性,这样WebAPI框架就可以读取它们

编辑

如果有人想知道我到底想要什么,我想详细解释一下

public interface IMyService
{
    IEnumerable<MyEntity> GetAll();
}

public class MyServiceImpl : IMyService
{
    public IEnumerable<MyEntity> GetAll()
    {
        return new List<MyEntity>(); //TODO: Get from database!
    }
}

public class MyServiceApiController : ApiController,IMyService
{
    private readonly IMyService _myService;

    public MyServiceApiController(IMyService myService)
    {
        _myService = myService;
    }

    public IEnumerable<MyEntity> GetAll()
    {
        return _myService.GetAll();
    }
}
公共接口IMyService
{
IEnumerable GetAll();
}
公共类myservicecimpl:IMyService
{
公共IEnumerable GetAll()
{
返回新列表();//TODO:从数据库获取!
}
}
公共类MyServiceAppController:ApiController,IMyService
{
私有只读IMyService\u myService;
公共myservicepicontroller(IMyService myService)
{
_myService=myService;
}
公共IEnumerable GetAll()
{
return _myService.GetAll();
}
}
假设我有一个由MyServiceImpl实现的IMyService。我想制作一个Api控制器,以便能够从web使用此服务。 但正如您所看到的,api控制器只是实际服务的代理。那么,我为什么要写它呢?我可以使用castle windsor动态创建它

这是我的想法,几乎在我的新项目()中完成了。但若我需要向api控制器的GetAll方法添加一些属性(比如Authorize),该怎么办呢。我不能直接添加,因为没有这样的类,它是castle动态代理

所以,除了这个问题。我想知道是否可以向synamic代理类的方法添加属性。

再次查看该项目 我还想知道如何定义,以便在iSeries设备上定义RoutePrefix,并在操作上定义Route。 幸运的是,我终于知道了如何为代理定义自定义属性

public class CustomProxyFactory : DefaultProxyFactory
{
    #region Overrides of DefaultProxyFactory

    protected override void CustomizeOptions(ProxyGenerationOptions options, IKernel kernel, ComponentModel model, object[] arguments)
    {
        var attributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new[] { typeof(string) }), new object[] { "CustomizeOptions" });
        options.AdditionalAttributes.Add(attributeBuilder);
    }

    #endregion
}

/// <summary>
/// 用户信息服务
/// </summary>
[Description("IUserInfoService")]
public interface IUserInfoService
{
    /// <summary>
    /// 获取用户信息
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    [Description("IUserInfoService.GetUserInfo")]
    UserInfo GetUserInfo([Description("IUserInfoService.GetUserInfo name")] string name);
}

/// <summary>
/// 用户信息服务
/// </summary>
[Description("UserInfoService")]
public class UserInfoService : IUserInfoService
{
    /// <summary>
    /// 获取用户信息
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    [Description("UserInfoService.GetUserInfo")]
    public virtual UserInfo GetUserInfo([Description("UserInfoService.GetUserInfo name")] string name)
    {
        return new UserInfo { Name = name };
    }
}

using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
[TestFixture]
public class AttributeTests
{
    /// <summary>
    /// Reference to the Castle Windsor Container.
    /// </summary>
    public IWindsorContainer IocContainer { get; private set; }
    [SetUp]
    public void Initialize()
    {
        IocContainer = new WindsorContainer();
        IocContainer.Kernel.ProxyFactory = new CustomProxyFactory();
        IocContainer.Register(
            Component.For<UserInfoService>()
                .Proxy
                .AdditionalInterfaces(typeof(IUserInfoService))
                .LifestyleTransient()
            );

    }

    /// <summary>
    /// 
    /// </summary>
    [Test]
    public void GetAttributeTest()
    {
        var userInfoService = IocContainer.Resolve<UserInfoService>();
        Assert.IsNotNull(userInfoService);
        var type = userInfoService.GetType();
        Assert.IsTrue(type != typeof(UserInfoService));
        var attribute = type.GetCustomAttribute<DescriptionAttribute>();
        Assert.IsTrue(attribute != null);
        Trace.WriteLine(attribute.Description);

        var method = type.GetMethod("GetUserInfo");
        attribute = method.GetCustomAttribute<DescriptionAttribute>();
        Assert.IsTrue(attribute != null);
        Trace.WriteLine(attribute.Description);

        var parameter = method.GetParameters().First();
        attribute = parameter.GetCustomAttribute<DescriptionAttribute>();
        Assert.IsTrue(attribute != null);
        Trace.WriteLine(attribute.Description);
    }
}
公共类CustomProxyFactory:DefaultProxyFactory
{
#DefaultProxyFactory的区域覆盖
受保护的覆盖无效自定义选项(ProxyGenerationOptions选项、IKernel内核、ComponentModel模型、object[]参数)
{
var attributeBuilder=new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new[]{typeof(string)}),new object[]{“CustomizeOptions”});
options.AdditionalAttributes.Add(attributeBuilder);
}
#端区
}
/// 
/// 用户信息服务
/// 
[说明(“iUserInfo服务”)]
公共接口IUSerInfo服务
{
/// 
/// 获取用户信息
/// 
/// 
/// 
[说明(“iuserinfo.GetUserInfo”)]
UserInfo GetUserInfo([Description(“iuserinfo.GetUserInfo name”)]字符串名);
}
/// 
/// 用户信息服务
/// 
[说明(“用户信息服务”)]
公共类UserInfoService:IUserInfoService
{
/// 
/// 获取用户信息
/// 
/// 
/// 
[说明(“UserInfoService.GetUserInfo”)]
公共虚拟UserInfo GetUserInfo([Description(“UserInfoService.GetUserInfo name”)]字符串名称)
{
返回新的UserInfo{Name=Name};
}
}
使用DescriptionAttribute=System.ComponentModel.DescriptionAttribute;
[测试夹具]
公共类属性测试
{
/// 
///温莎城堡集装箱的参考资料。
/// 
公共IWindsorContainer IocContainer{get;private set;}
[设置]
公共无效初始化()
{
IocContainer=新WindsorContainer();
IocContainer.Kernel.ProxyFactory=新的CustomProxyFactory();
IocContainer.寄存器(
用于()的组件
代理
.附加接口(类型(IUSerInfo服务))
.生活方式
);
}
/// 
/// 
/// 
[测试]
public void GetAttributeTest()
{
var userInfoService=IocContainer.Resolve();
IsNotNull(userInfoService);
var type=userInfoService.GetType();
IsTrue(type!=typeof(UserInfoService));
var attribute=type.GetCustomAttribute();
Assert.IsTrue(属性!=null);
Trace.WriteLine(attribute.Description);
var method=type.GetMethod(“GetUserInfo”);
attribute=method.GetCustomAttribute();
Assert.IsTrue(属性!=null);
Trace.WriteLine(attribute.Description);
var parameter=method.GetParameters().First();
attribute=parameter.GetCustomAttribute();
Assert.IsTrue(属性!=null);
Trace.WriteLine(attribute.Description);
}
}

@hikalkan我也面临同样的问题,我也在寻找解决方案。我能遇到的最好的情况是


使用新的包装器代理控制器(在我的例子中是动态控制器),该包装器在类本身及其方法中设置这些属性。

Web API真的读取这些属性吗?我对MVC的习惯是,只有
控制器
基类读取其派生类上的属性,因此您可以安全地包装此类,因为MVC只与
IController
交互。对于Web API,这不是同样的工作方式吗?因此,
ApiController
读取属性,而Web API只与
IHttpController
交互?否则,
IHttpController
抽象将被破坏。WebAPI具有一些属性,例如Authorize、FromBody和FromUri属性(请参阅)。另外,我不能在我的服务层中定义这样的属性,因为它独立于WebAPI层。因此,当我创建一个动态web api时,我必须将这些属性注入新创建的web api类。此外,我可能还想将自定义属性添加到代理类、方法(甚至是方法的参数)中。如果我没有弄错的话,您可以将任何修饰符包装在
ApiController
中,这些属性仍将被应用(因为ApiController会自我反射