8

У меня есть класс, который я прокси-сервер с помощью Dynamic Proxy. Я хочу добавить некоторые настраиваемые атрибуты к прокси-методам (которые не определены в прокси-классе). Это возможно.Могу ли я определить пользовательские атрибуты для прокси-типа в Castle Windsor

Я хочу это, потому что хочу сгенерировать уровень веб-API ASP.NET для уровня обслуживания моего приложения. Я проксированные службы (с наследованием от ApiController и дополнительные интерфейсы IMyService), он отлично работает, но я хочу добавить специальные атрибуты WebAPI к этому недавно созданному классу Dynamic, поэтому среда Web API может их прочитать.

EDIT:

Я хочу объяснить подробные, если кто-то хочет знать, что я хочу на самом деле.

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, который реализован MyServiceImpl. И я хочу, чтобы контроллер Api мог использовать эту услугу из Интернета. Но, как вы видите, контроллер api - это просто прокси для реального обслуживания. Итак, зачем мне писать? Я могу динамически создавать его с помощью виндзора замка.

Это моя идея и почти все сделано в моем новом проекте (https://github.com/hikalkan/aspnetboilerplate). Но что, если мне нужно добавить некоторый атрибут (например, Authorize) в метод GetAll для контроллера api. Я не могу добавить, так как нет такого класса, это динамический прокси-замок.

Итак, помимо этой проблемы. Я хочу знать, можно ли добавить атрибут к методу синтаксического прокси-класса.

+0

ли Web API действительно читать эти атрибуты ? То, что я привык с MVC, состоит в том, что только базовый класс 'Controller' читает атрибуты на своих производных классах, поэтому вы можете безопасно обернуть такой класс, поскольку MVC взаимодействует только с' IController'. Разве это не работает для Web API? Таким образом, 'ApiController' читает атрибуты, в то время как Web API взаимодействует только с' IHttpController'? В противном случае абстракция 'IHttpController' будет нарушена. – Steven

+0

WebAPI имеет некоторые атрибуты, такие как атрибуты Authorize, FromBody и FromUri (см. Http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web- апи). Кроме того, я не могу определить такие атрибуты на моем сервисном уровне, поскольку он не зависит от уровня веб-api. Поэтому, когда я создаю динамический веб-api, мне приходится вводить эти атрибуты только что созданному веб-классу api. – hikalkan

+0

Кроме того, я могу добавить пользовательские атрибуты к прокси-классу, методы (даже к параметрам метода) за пределами этого случая. – hikalkan

ответ

2

снова видим, что проект https://github.com/aspnetboilerplate/aspnetboilerplate/issues/55 Я также хотел бы знать, как, так что я могу определить RoutePrefix на IService и пути на действии. К счастью, я наконец-то знаю, как определить пользовательские атрибуты для прокси.

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

@hikalkan У меня возникла такая же проблема, и я искал решение. Лучшее, что я мог бы столкнуться был How to add an attribute to a property at runtime

Proxy контроллер (в моем случае динамический контроллер) с новой обертке, которые устанавливают эти атрибуты в самой компании и ее методы класса ..