Hi,

Am I misunderstanding something here. Is it not allowed to have (static) methods in DO4 Classes? I added a 'CheckUser' method to my User Class and now Postsharp gives me an exception. Is this by desing or a bug?

Regards Paul Sinnema Diartis AG

Here is the code

using System;
using Xtensive.Storage;
using System.Linq;

namespace AnyMatrixModel
{
    enum SecurityLevel
    {
        Guest,
        User,
        Editor,
        Administrator
    }

    [Serializable]
    public class User : AbstractEntity
    {
        [Field(Length=Int32.MaxValue)]
        public string FirstName { get; set; }

        [Field(Length=Int32.MaxValue)]
        public string LastName { get; set; }

        [Field(Length = Int32.MaxValue)]
        public string UserId { get; set; }

        [Field(Length = Int32.MaxValue)]
        public string Password { get; set; }

        [Field]
        public int SecurityLevel { get; set; }

        public static bool CheckUser(string userId, string password, out string message)
        {
            message = string.Empty;

            var q = from usr in Query.All<User>()
                    where usr.UserId == userId
                    && usr.Password == password
                    select usr;

            User user = q.FirstOrDefault();

            if (user == null)
            {
                message = "UserId or Password is wrong";
                return false;
            }

            return true;
        }
    }
}

And here is the exception.

Error   1   Unhandled exception (2.0.5.1205, 64 bit, CLR 4.0, Release): System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at PostSharp.AspectWeaver.Transformations.ArgumentsWriter.^C0S6plPn.EmitStoreByRefArgument(Int32 _0, InstructionWriter _1, Action`1 _2)
   at ^1gq46AVh1jKu.^/1JyDPoZ5pES.^h4HWFf13.^MNbxG17j(ArgumentsWriter _0, MethodMappingWriter _1, InstructionWriter _2)
   at ^1gq46AVh1jKu.^/1JyDPoZ5pES.^h4HWFf13.WeaveOnException(InstructionBlock _0, ITypeSignature _1, InstructionWriter _2)
   at PostSharp.AspectInfrastructure.Helpers.MethodBodyWrappingImplementation.Implement(Boolean hasOnEntry, Boolean hasOnSuccess, Boolean hasOnExit, ITypeSignature[] exceptionTypes)
   at ^1gq46AVh1jKu.^/1JyDPoZ5pES.^h4HWFf13.^r4DISfQ8()
   at ^1gq46AVh1jKu.^/1JyDPoZ5pES.Implement(MethodBodyTransformationContext _0)
   at ^j1TTpdjykhlv.^LuETqvLKzZPB(MetadataDeclaration _0, MetadataDeclaration _1, MethodSemantics _2, InstructionBlock _3, Object[] _4, CanonicalMethodMapping _5, LocalVariableSymbol _6, InstructionSequence _7, TypeDefDeclaration _8, PipelineTransversalState _9)
   at ^MznFwdI/QV4L.^HvVDHXOj(MetadataDeclaration _0, IDependencyTransformationInstance[] _1, PipelineTransversalState _2, MethodSemantics _3)
   at PostSharp.AspectInfrastructure.AspectInfrastructureTask.^jwku0geZ(MetadataDeclaration _0, PipelineTransversalState _1, MethodSemantics _2, Boolean _3)
   at PostSharp.AspectInfrastructure.AspectInfrastructureTask.^jwku0geZ(IMetadataDeclaration _0, PipelineTransversalState _1, MethodSemantics _2)
   at PostSharp.AspectInfrastructure.StructuredDeclarationDictionary`1.^d+wOzSPF(IMetadataDeclaration _0, Func`2 _1)
   at PostSharp.AspectInfrastructure.StructuredDeclarationDictionary`1.^+g+TCqVg(TypeDefDeclaration _0, Func`2 _1, Set`1 _2)
   at PostSharp.AspectInfrastructure.StructuredDeclarationDictionary`1.^fJqG(Func`2 _0)
   at PostSharp.AspectInfrastructure.AspectInfrastructureTask.Execute()
   at PostSharp.Extensibility.Project.ExecutePhase(String phase)
   at PostSharp.Extensibility.Project.Execute()
   at PostSharp.Hosting.PostSharpObject.ExecuteProjects()
   at PostSharp.Hosting.PostSharpObject.InvokeProject(ProjectInvocation projectInvocation)  C:\Users\Paul\Documents\Visual Studio 2010\Projects\AnyMatrix\AnyMatrixModel\POSTSHARP  AnyMatrixModel

Updated at 22.06.2010 16:16:24

Advice from functional programming: avoid out and ref parameters;

Works just fine:

Regards Paul Sinnema Diartis AG

using System;
using Xtensive.Storage;
using System.Linq;
using AnyMatrixModel.Exceptions;

namespace AnyMatrixModel
{
    enum SecurityLevel
    {
        Guest,
        User,
        Editor,
        Administrator
    }

    [Serializable]
    public class User : AbstractEntity
    {
        [Field(Length=Int32.MaxValue)]
        public string FirstName { get; set; }

        [Field(Length=Int32.MaxValue)]
        public string LastName { get; set; }

        [Field(Length = Int32.MaxValue)]
        public string UserId { get; set; }

        [Field(Length = Int32.MaxValue)]
        public string Password { get; set; }

        [Field]
        public int SecurityLevel { get; set; }

        /// <summary>
        /// Finds the User with UserId and Password and returns the User object
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static User CheckUser(string userId, string password)
        {
            var q = from usr in Query.All<User>()
                    where usr.UserId == userId
                    && usr.Password == password
                    select usr;

            User user = q.FirstOrDefault();

            if (user == null)
            {
                throw new LoginFailedException("UserId or Password is wrong");
            }

            return user;
        }
    }
}

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Jun 21 '10 at 17:50

Paul%20Sinnema's gravatar image

Paul Sinnema
261868896


One Answer:

Looks like there is one more bug related to out/ref parameters in PostSharp.

To workaround it, try to get rid of out parameter.

I'll report the issue to SharpCrafters. Additionally, I'm going to build new DO4 RC based on latest PostSharp (2.0 RC1) today - may be the issue is already fixed there.


Found similar issue with ref parameter, that was already fixed: viewtopic.php?f=29&t=5887&p=14562&hilit=ref#p14562


Advice from functional programming: avoid out and ref parameters; use Tuple<...> (not our own, but from .NET 4.0) to return a set of them instead. Xtensive.Core provides few alternatives as well:

  • Pair<tleft,tright> and Pair<t> types
  • Triplet<tfirst,tsecond,tthird> and Triplet<t> types

They're structs - that's their only difference with Tuple<t1,t2> and Tuple<t1,t2,t3> from .NET 4.0. So in many cases their usage might be more effecient. Tuples are preferable for longer lists (may be even starting from 3 values).

Disadvantage: structure of such result isn't self-describing.

answered Jun 21 '10 at 19:46

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

Good then ;)

(Jun 21 '10 at 19:46) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA