Results 1 to 4 of 4

Thread: Copying of custom attributes doesn't work for ServiceBehavior Wcf attribute and AOP

  1. #1
    Join Date
    Jun 2007
    Posts
    2

    Default Copying of custom attributes doesn't work for ServiceBehavior Wcf attribute and AOP

    Alex, Bruno,
    I followed the discussion on this forum about attributes being copied and currently I'm investigating the following issue:

    When we create an aoped instance of the WebService class (which is as well Wcf service) via WebserviceExporter we are getting ArgumentNullException in the GetCustomAttributes method for ServiceBehavior attribute (ConfigurationName can't be null).

    You can reproduce the problem in the following way (no need for webservice):

    IWcfService service = new WcfServiceImpl();

    ProxyFactory pf1 = new ProxyFactory(service);
    pf1.AddAdvisor(new DefaultPointcutAdvisor(new NopInterceptor()));

    IWcfService proxy0 = pf1.GetProxy() as IWcfService;

    Assert.IsNotNull(proxy0, "pf1.GetProxy() as IWcfService should not evaluate as null!");


    ProxyFactory pf2 = new ProxyFactory(pf1.GetProxy());
    pf2.AddAdvisor(new DefaultPointcutAdvisor(new NopInterceptor()));

    IWcfService proxy1 = pf2.GetProxy() as IWcfService;


    It is second .GetProxy that is leading to the exception when attributes are copied not from the original type but from the proxy of the original class.

    for the sample class as:

    [ServiceBehavior(Name = "WcfServiceWithServiceBehavior", Namespace = "http://spring.net/wcf.tests/2006")]
    public class WcfServiceImpl : IWcfService
    {
    public string WcfMethod(int count)
    {
    return count.ToString();
    }
    }


    We are commited to fix the problem, though when I see the code where exception is hapenning:

    protected virtual IList GetTypeAttributes(Type type)
    {
    // TODO : attributes override

    ArrayList attributes = new ArrayList();

    if (this.ExposeTargetAttributes)
    {
    // add attributes that apply to the target type
    attributes.AddRange(type.GetCustomAttributes(false ));
    }


    reading the forums and seeing this TODO in the code, I'd like to discuss what is your vision for fixing this problem before we apply our solution.

    You can be on Spring.One I guess Then my java Spring collegue may try to contact you there.

  2. #2
    Join Date
    Oct 2005
    Location
    Toulouse, France
    Posts
    1,409

    Default

    Hi Stan,

    You lucky I'm not at Spring.One today
    I'll be there tomorrow only for "day 2" conferences, so I should meet your collegue there.

    The problem here is the ConfigurationName property of the ServiceBehaviorAttribute, the setter checks if the value is null or empty and throw an exception in that case.
    When Spring creates the attribute instance for the proxy type, via the Reflection.Emit.CustomAttributeBuilder, it copies all properties. To simplify, it does something like that :
    proxyServiceBehaviorAttribute.ConfigurationName = targetServiceBehaviorAttribute.ConfigurationName;
    And ConfigurationName is null in your case...

    Just try to set the ConfigurationName property with a correct value, it should work (unless there is another property with the same behavior).


    I hope I can talk about this and the metadata container with Aleks tomorrow.

    Btw, Are you using the current (not complete) WCF integration ?

    HTH,
    Bruno
    Last edited by Bruno Baia; 06-20-2007 at 10:13 PM.
    My english is as poor as my taylor is rich

  3. #3
    Join Date
    Jun 2007
    Posts
    2

    Default

    Thanks Bruno and all the best with your trip.

    It might not be such a natural solution to set those in the ServiceBehavior attributes applied to a class.
    Imagine I need to tell to my fellow developers: Set ConfigurationName to something, set TransactionTimeout to something, not that we have got such a configuration element in the config file or use Transactions for this service, it is just because we use Spring ....

    I can't get away with this .

    Just to brainstorm:
    We may avoid setting properties on the attribite that are null, we can avoid including it in the array of PropertyInfo send to the CustomAttributeBuilder.

    We can update the following code in the ReflectionUtils.CreateCustomAttribute method from:
    Code:
    if (pi.CanRead && pi.CanWrite)
    {
    	tmpProps.Add(pi);
    }
    To:
    Code:
    if (pi.CanRead && pi.CanWrite && pi.GetValue(sourceAttribute, null) != null)
    {
    	tmpProps.Add(pi);
    }

    I ran only few tests, but it seems to do the thing for us.
    I can't currently see any problem with excluding those properties and it seems to be right to exclude them.

    Let me please know what now

    regards and thanks,
    Stan
    http://blog.decaresystems.ie/

    P.S. As for the version we use, it is 20070515-2213 and we are going to update to 20070618-2221 in a couple of days, so looking forward to play with WcfQuickStarts
    Last edited by Stan D.; 06-21-2007 at 02:24 PM.

  4. #4
    Join Date
    Oct 2005
    Location
    Toulouse, France
    Posts
    1,409

    Default

    Quote Originally Posted by Stan D. View Post
    It might not be such a natural solution to set those in the ServiceBehavior attributes applied to a class.
    I know, just wanted to know if it works and there wasn't anther problem.


    The solution you implemented works for your case, but not always.
    The Order property of the XmlElementAttribute is a good example.

    A solution is to create a default instance of the attribute and compare property values to recognize default values.
    This will not work if a getter change the value, but this is less probable.
    Attributes with no property setter is another pb and will be treated individualy (see TransactionAttribute or GuidAttribute)

    I've created an issue in JIRA.

    Bruno
    Last edited by Bruno Baia; 06-24-2007 at 11:25 PM.
    My english is as poor as my taylor is rich

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •