PostSharp Official Blog Just another WordPress weblog 2008-11-13T07:34:36Z WordPress http://www.postsharp.org/blog/feed/atom/ gael http://www.postsharp.org/ <![CDATA[Inheritance of Aspects in PostSharp 1.5 CTP 2]]> http://www.postsharp.org/blog/2008/11/inheritance-of-aspects-in-postsharp-15-ctp-2/ 2008-11-13T07:34:36Z 2008-11-13T07:34:36Z Microsoft PDC 2008 is over, as are American presidential elections. We can now talk about something exiting again and hope it will gain some momentum in the community (thus blogging about boring technical details during PDC was intentional).

It’s maybe the most exciting feature of PostSharp after PostSharp itself: aspects are now inheritable.

A code sample worthing a hundred words, here is what is now possible:

public interface IDiary
{
    Contact TryFindContact([NonEmpty] string name);

    [return: NonNull]
    Contact FindContact([NonEmpty] string name);

    void Update([NotNull] Contact contact);
}

 

The aspects (here NonEmpty and NonNull) are applied on methods of an interface… but are effective on all implementations of this interface!

(Oh yes, for this to work correctly, you need to download the latest build from http://download.postsharp.org/builds/1.5 — the CTP 2 contained some bugs that have been solved in the mean time).

The implementation of these aspects does not use Laos, but a dedicated plug-in that generates optimal MSIL instructions. You can download the plug-in using an SVN client from https://postsharp-user-plugins.googlecode.com/svn/trunk/1.5/Torch.

The inheritance feature is indeed implemented at the level of MulticastAttribute, and not directly in Laos. It means that you can use it inside any plug-in. But let’s now see an example using Laos.

Simple Invariant Checking

Here is an interesting first example of this feature; it is both simple and useful.

We want to check invariants, and we want to do it simply. With PostSharp 1.5, checking invariants can be as simple as implementing an interface, say IConsistant.

public interface IConsistant
{
    void CheckConsistency();
}

When an object implements the IConsistant assembly, we want the CheckConsistency method to be "automagically" invoked after each non-private instance method.

It’s possible by applying a single custom attribute, say [ConsistantAspect] to the IConsistant interface:

[ConsistantAspect]
public interface IConsistant

This custom attribute is unbelievably simple:


[AttributeUsage(AttributeTargets.Interface)]
[MulticastAttributeUsage(MulticastTargets.Method,
    TargetMemberAttributes = MulticastAttributes.Public | MulticastAttributes.Protected | MulticastAttributes.Internal |
    MulticastAttributes.Instance,
    Inheritance = MulticastInheritance.Multicast)]
[Serializable]
public sealed class ConsistantAspect : OnMethodBoundaryAspect
{
    public override void OnSuccess(MethodExecutionEventArgs eventArgs)
    {
        ((IConsistant) eventArgs.Instance).CheckConsistency();
    }
}


 

Basically, we have create an OnMethodBoundaryAspect and we implement the OnSuccess handler that invokes the CheckConsitency method when the target method has successfully completed. The AttributeUsage custom attribute restricts the use of this aspect to interfaces; actually, we will use it only once: on the IConsistant method.

The interesting part if the custom attribute MulticastAttributeUsage on the top of that:

  • The property TargetMemberAttributes is old and known: here we define that we want to apply the aspect only to non-private instance methods.
  • The property Inheritance is the new and interesting one: the value Multicast means that the aspect should be inherited (from the interface to classes implementing the interface) and then multicast to all methods matching TargetMemberAttributes.

As a result, when we implement the interface and have invariants checked automatically:

class Cashbox : IConsistant
{
    public decimal Balance { get; private set; }

    public void Debit(decimal amount)
    {
        this.Balance -= amount;
    }

    public void Credit(decimal amount)
    {
        this.Balance += amount;
    }

    public void CheckConsistency()
    {
        if ( Balance < 0 )
            throw new Exception("Invalid balance.");
    }

}

 

As you can see, no aspect is directly applied on Cashbox or on its methods. Aspects are inherited from IConsistant and then propagated to all public instance methods.

I’ll blog more about this feature later.

Happy PostSharping!

-gael

]]>
1
gael http://www.postsharp.org/ <![CDATA[Partial Trust, Windows Azure & Pluggable Serializers]]> http://www.postsharp.org/blog/2008/11/partial-trust-windows-azure-pluggable-serializers/ 2008-11-03T20:53:47Z 2008-11-03T20:53:47Z Would I be a perfect .NET developer if I did not blog about Windows Azure? I let the response to your own judgment, but even if you don’t agree on that statement read on.

If you try to deploy a PostSharp-enabled assembly into the Development Fabric, you will probably get the following exception:

[SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
   System.Runtime.Serialization.Formatters.Binary.ObjectReader.CheckSecurity(ParseRecord pr) +10107255
   System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseArray(ParseRecord pr) +155
   System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseObject(ParseRecord pr) +151
   System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadArray(BinaryHeaderEnum binaryHeaderEnum) +581
   System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run() +283
   System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) +559
   System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) +326
   System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) +33
   PostSharp.Laos.Serializers.BinaryLaosSerializer.Deserialize(Stream stream) in BinaryLaosSerializer.cs:46
   PostSharp.Laos.LaosSerializer.Deserialize(Assembly assembly, String resourceName) in LaosSerializer.cs:68
   ~PostSharp~Laos~Implementation..cctor() +365

Don’t panic, it is not the end of the story.

Clearly, there is a security exception. Looking at the stack trace, you see that the exception occurs in the BinaryFormatter.Deserialize. Indeed, the binary formatter requires full trust and… code running inside Windows Azure is only partially trusted.

I could have written the same for code running inside SQL Server 2005, but it’s less hyped: very often, when your code is hosted, it is not granted full trust.

Pluggable Serializers

If you are new to PostSharp, you may wonder why BinaryFormatter is invoked at runtime. In fact, at build time, aspects are instantiated and serialized into a binary stream. This stream is stored in a managed resource in the assembly and deserialized at runtime. That’s why the binary formatter is invoked.

Fortunately, PostSharp 1.5 CTP 2 comes with a new feature called pluggable serializers. Before, you had no choice: aspects were always serialized using the BinaryFormatter. It is the best tool for the job for most situations, but, as you can see here with partial-trust scenarios, it is not always possible to use it.

But there are other serializers in .NET, isn’t it? So why not to use them? That’s exactly the idea behind pluggable serializers: you can now choose the serializer used to to serialize aspects at build time and deserialize them at rutime.

PostSharp 1.5 comes with three serializers: BinaryLaosSerializer (relying on BinaryFormatter), XmlLaosSerializer (relying on XmlSerializer) and StateBagSerializer (requiring manual implementation in all classes, see documentation). All implement the abstract class PostSharp.Laos.Serializer; if you need another serializer, you can develop your.

Once you have selected a serializer, you should tell PostSharp to use it for your aspect. This is done by applying the custom attribute LaosSerializerAttribute to your aspect class. For instance:

[LaosSerializer(typeof(XmlLaosSerializer))]
public class SomeAspect : OnMethodBoundaryAspect
{   [XmlElement] public string Name;
  public override void OnEntry(MethodExecutionEventArgs eventArgs)
  {

  }
}

Since this serializer does not require full trust… it simply works in Windows Azure!

Why do I need a serializer, anyway?

Excellent remarks. Serializers are good when there there is some non-trivial state to be stored. But if your aspect is an isolated custom attribute with some public fields or public properties, it is far better to instantiate the attribute at runtime using the values provided to construct the custom attribute.

For instance, if a custom attribute instance is defined by:

[SomeAspect(Name = "Hello")]

It would be much better (faster and byte-wise more compact) to create the aspect using the following code:

SomeAspect instance = new SomeAspect { Name = "Hello" };

This is exactly what happens if you use the custom attribute LaosSerializerAttribute and pass null to the constructor parameter. The aspect won’t be serialized; it will be instantiated and initialized at runtime by some auto-generated code. And this is actually the way aspects for Compact Framework and Silverlight work.

So remember: even if you don’t write partially trusted code, you can still use the "null serializer" to improve the size and performance of your assemblies.

Happy PostSharping!

-gael

]]>
1
gael http://www.postsharp.org/ <![CDATA[What really changed between 1.0 and 1.5 #2: Understanding reflection wrappers]]> http://www.postsharp.org/blog/2008/10/what-really-changed-between-10-and-15-2-understanding-reflection-wrappers/ 2008-10-28T20:44:04Z 2008-10-28T20:43:42Z In the first part of this article, I explained that Silverlight (SL) or Compact Framework (CF) assemblies were not loaded in the CLR. However, as you could have noticed in the last sample, user code still receives instances of Type, FieldInfo, or MethodBase. How is this possible, since assemblies are not loaded, even not “for reflection only”?

Well, here, there is some magic. All these classes (Type, FieldInfo, or MethodBase) are actually abstract ones. You are used to runtime implementations (RuntimeType, RuntimeFieldInfo and so on). But in PostSharp, you don’t get runtime implementations (fairly enough, since we are at build time!), so you get so-called reflection wrappers.

Reflection wrappers are an emulation of System.Reflection that purely relies on the PostSharp object model.

Once again to be sure: Reflection wrappers look like System.Reflection but it is not System.Reflection.

And now something even more important:

Even if you target the full framework, you receive reflection wrappers instead of runtime objects.

And this is another big difference between 1.0 and 1.5: 1.0 was not very strict about this; sometimes you received reflection wrappers and sometimes (notoriously in CompoundAspect) runtime objects. In version 1.5, you always receive reflection wrappers.

Gotchaes that will get you

There are subtle differences between PostSharp reflection wrappers and native System.Reflection. If you don’t understand them, you risk spending hours in debugging.

  • Never compare by reference. That is, never use the equal (==) operator. Unlike native System.Reflection, two instances can represent the same thing. What is more, comparing a wrapper to a native element of System.Reflection never works. So use the Equals method instead of the == operator.
  • Never uses native equality or inheritance comparing methods. So don’t use typeof(Guid).Equals(targetType) but targetType.Equals(typeof(Guid)). I know this sucks (equality is supposed to be commutative), but… there is no workaround!

The safest way is to use the class PostSharp.Reflection.ReflectionTypeComparer for all comparisons… or when you build a dictionary.

Getting the underlying runtime object

That being said, unless you target SL or CF, you can always retrieve the “usual” runtime/native object and work, well, as usually.

First, let me give you a good reason not to do it: doing so would load the type in the CLR, which would have some performance penalty, and may sometimes not succeed at all (for instance if you have an unresolved extern method — unresolved because you want to implement them using PostSharp, for instance). It seems that static constructors are not invoked just because of loading the Type object, and I hope (but am not sure) that methods are not JIT compiled. So the reason is maybe good but arguably small, I have to admit.

So if you don’t care about the eventual performance penalty, go for it: the secret is to retrieve the property Type.UnderlyingSystemType, FieldInfo.UnderlyingSystemField or MethodBase.UnderlyingSystemMethod. You will get a real-native-runtime-system object.

Since even PostSharp 1.5 loads assemblies in the CLR (when not targeting SL or CF), the difference is maybe slight. But future versions of PostSharp may avoid loading assemblies in the CLR unless strictly necessary. And by requiring the underlying runtime element, you make it necessary… maybe unnecessarily.

Getting the assembly

A problem with reflection wrappers is that Assembly is a sealed class; we cannot override it. So you cannot get a transparent assembly wrapper. So instead of getting an Assembly (typically in a CompoundAspect applied at assembly level), you will get an IAssemblyWrapper. And, yes, you can use IAssemblyWrapper.UnderlyingSystemAssembly if you like.

Conclusion

Pay attention: reflection wrappers are not ‘usual’ System.Reflection objects!

]]>
0
gael http://www.postsharp.org/ <![CDATA[What really changed between 1.0 and 1.5 #1: Targeting Silverlight and the Compact Framework]]> http://www.postsharp.org/blog/2008/10/what-really-changed-between-10-and-15-1-targeting-silverlight-and-the-compact-framework/ 2008-10-28T19:56:06Z 2008-10-28T19:39:51Z Setting aside the “exciting new features” of 1.5, there is some fundamental difference between 1.0 and 1.5. Although this difference will hardly be detected by beginners, advanced (PostSharp Core) and even intermediate (advanced PostSharp Laos) ones will surely hit it soon: PostSharp 1.5 is completely independent from System.Reflection.

It has been written that PostSharp Core is built on the top of System.Reflection: this is not true. PostSharp has from the very beginning its own reflection engine, for the good reason that System.Reflection is not good enough for the job. But PostSharp 1.0 relied on reflection for some operations. Indeed, it required every processed assembly to be loaded in the CLR. PostSharp 1.0 read the mapped PE file from memory after it has been loaded loaded by the CLR. A great benefit of this approach is that we don’t need to load the assembly twice in memory.

So it was not possible, in PostSharp 1.0, to load an assembly in PostSharp without loading it in the application domain.

The first reason I had to redesign this was Mono: memory mapping of modules was not as clearly defined as in the Microsoft implementation (where the origin of the PE file is simply the HMODULE of module), so it was necessary to read the assembly from disk. But assemblies could still be loaded in the CLR besides, so we could still rely on System.Reflection.

The second and most compelling reason was the support of other variants of the framework, namely Silverlight and Compact Framework. Shortly speaking, it is not possible to load the modules into the CLR, and therefore neither possible to use System.Reflection. It was consequently necessary to make PostSharp completely independent from System.Reflection.

So remember: when using PostSharp for Silverlight (SL) or the Compact Framework (CF), the assembly being transformed is never loaded in the CLR.

Instantiation of aspects in SL and CF

Remember that, when you target the full .NET Framework using PostSharp, instances of aspects are created at build time; they are then serialized and stored as a binary blob as a managed resource.

But how can we instantiate aspects if we cannot load their type? No magic here: we cannot. So we don’t. If you target SL or CF, your aspects will be instantiated at runtime and no serialization or deserialization will occur. Period.

You may be curious how aspects are actually instantiated at runtime. Very easily: the PostSharp Laos weaver emits instruction that invoke the aspect constructor with the correct parameters and sets named fields and properties. So finally you get pure MSIL code — and it is even much faster than deserialization.

Compile-time semantics in SL and CF

A second and more subtle problem is how will work compile-time semantics (like CompileTimeValidate, CompileTimeInitialize and GetOptions). Simply: they cannot be implemented in a SL or CF assembly. CF and SL variants of PostSharp.Laos simply don’t contain these methods. There are two kind of workaround:

Custom Attribute

Custom attributes configuring aspects, for instance classes derived from OnExceptionAspect should be annotated with OnExceptionAspectConfigurationAttribute to specify which exception should be caught (this replaces a build-time call to the GetExceptionType method).

using PostSharp.Laos;

namespace PostSharp.Samples.Silverlight.Aspects
{
    [OnExceptionAspectConfiguration(ExceptionType = "System.SystemException, mscorlib")]
    public class ExceptionHandlerAttribute : OnExceptionAspect
    {
        public override void OnException(MethodExecutionEventArgs eventArgs)
        {
            // Show a dialog box.
        }
    }
}

External Aspect

More complex logic can be implemented in an assembly built for the normal .NET Framework. So instead of CompoundAspect, you should create a class inheriting ExternalAspect and annotate the class with the ExternalAspectConfigurationAttribute custom attribute. This custom attribute specifies the class implementing the aspect:

using PostSharp.Extensibility;
using PostSharp.Laos;

namespace PostSharp.Samples.Silverlight.Aspects
{
    [ExternalAspectConfiguration(
        "PostSharp.Samples.Silverlight.Impl.NotifyPropertyChangedImpl, PostSharp.Samples.Silverlight.Impl")]
    [MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Struct, PersistMetaData = false)]
    public class NotifyPropertyChangedAttribute : ExternalAspect
    {
    }
}

The implementation class should implement the interface IExternalAspectImplementation, defined in PostSharp.Laos.dll (not PostSharp.Laos.SL.dll or PostSharp.Laos.CF.dll):

 

You see the similarity with CompoundAspect. There are however some important differences: You don’t get the aspect instance because we are not able to create an aspect instance. But you get the object construction (IObjectConstruction), which specifies the aspect type, the constructor arguments, and the named arguments. The second thing is that, as you cannot receive an aspect instance, you cannot create an aspect instance to add it to the collection. So you have to add an ObjectConstruction instead.

Here is the body of ImplementAspect:

public void ImplementAspect(object target, IObjectConstruction aspectData,
                            LaosReflectionAspectCollection collection)
{
    // Get the target type.
    Type targetType = (Type) target;

    // On the type, add a Composition aspect to implement the INotifyPropertyChanged interface.

    collection.AddAspectConstruction(
        targetType,
        new ObjectConstruction(
            "PostSharp.Samples.Silverlight.Aspects.Impl.NotifyPropertyChangedCompositionAdvice, PostSharp.Samples.Silverlight.Aspects"),
        null);

    // Add a OnMethodBoundaryAspect on each writable non-static property.
    foreach (PropertyInfo property in targetType.GetProperties())
    {
        if (property.DeclaringType.Equals(targetType) && property.CanWrite)
        {
            MethodInfo method = property.GetSetMethod();

            if (!method.IsStatic)
            {
                collection.AddAspectConstruction(
                    method,
                    new ObjectConstruction(
                        "PostSharp.Samples.Silverlight.Aspects.Impl.NotifyPropertyChangedSetterAdvice, PostSharp.Samples.Silverlight.Aspects",
                        property.Name),
                    null);
            }
        }
    }
}

So writing aspects of intermediate complexity is much less convenient for CF/SL than for the full framework. Good news is that is still possible to do complex things, and that this complexity can be encapsulate so that aspect users actually don’t care.

]]>
0
gael http://www.postsharp.org/ <![CDATA[Using Automatic Properties with XPO Objects]]> http://www.postsharp.org/blog/2008/10/using-automatic-properties-with-xpo-objects/ 2008-10-28T14:25:55Z 2008-10-28T14:25:55Z It seems that making ORM easier to work with becomes one of the killer apps of PostSharp.

There were already PostSharp aspects for DataObjects.NET, Starcounter and NHibernate. Sean Kearon has now developed a library for Express Persistent Object (XPO).

For more information, please see the CodePlex project page and his blog.

Happy PostSharping!

-gael

]]>
0
gael http://www.postsharp.org/ <![CDATA[PostSharp 1.5 CTP 2 Reloaded]]> http://www.postsharp.org/blog/2008/10/postsharp-15-ctp-2-reloaded/ 2008-10-28T16:41:13Z 2008-10-28T14:05:22Z There was some high-coverage bug so I had to refresh CTP 2. You have to download it again if you already did it.

-gael

]]>
0
gael http://www.postsharp.org/ <![CDATA[Announcing PostSharp 1.5 CTP 2]]> http://www.postsharp.org/blog/2008/10/announcing-postsharp-15-ctp-2/ 2008-10-27T10:49:06Z 2008-10-27T10:49:06Z I am pleased to announce I have just released PostSharp 1.5 CTP 2 with exciting improvements over PostSharp 1.5 CTP 1 and of course PostSharp 1.0. Among the things you can be looking forward:

  • Aspect Inheritance. This is something many of you have longed for. You can now apply an aspect on a (non-sealed) class or a (non-sealed) virtual method and have the aspect automatically applied to all derived classes or methods. The same with interfaces. Since the feature is implemented at the level of MulticastAttibute. I will blog further about this feature in a next post, but if you are eager to try, everything is hidden behind the MulticastAttribute.AttributeInheritance and MulticastAttributeUsage.Inheritance properties!
  • Pluggable Aspect Serializers. If you cannot use the BinaryFormatter to serialize Laos aspects, you can now override the serializer implementation. You can even use no serializer at all and have the aspects constructed at runtime by ad-hoc MSIL instructions. And why would you need to do it? For instance for compatibility with code obfuscators (breaking the relationship between serialization and code), because of an extra need of speed or you need…
  • Support for Partial Trust: Since PostSharp Laos is not bound to the BinaryFormatter any more, you can now use assemblies transformed by PostSharp in partially-trusted scenarios. And this may become more important that you now imagine!
  • Built-in support for ASP.NET: It used to be available as a separate project; it is now merged in the principal trunk and will be fully supported.
  • Injection of Custom Attributes: This new aspect allows you to add custom attributes to any element (type, method, field, method, property, event, parameter, return value, assembly) from a CompoundAspect. See CustomAttributeInjectorAspect for details.
  • All the bug fixes up to PostSharp 1.0 SP 1.
  • The field injected by a CompositionAspect can be marked as non-serializable.

New features are not yet documented in the user guide (yet they are in the class reference); I will blog about them more in detail during next days.

Happy PostSharping!

-gael

]]>
0
gael http://www.postsharp.org/ <![CDATA[Pre-release of PostSharp 1.0 SP1]]> http://www.postsharp.org/blog/2008/10/pre-release-of-postsharp-10-sp1/ 2008-10-24T18:17:25Z 2008-10-24T16:26:45Z It is not a release, because I would need the bravest of you to test it (oh, come on, I tested it extensively in lab conditions!), but it’s another significant step forward: PostSharp 1.0 SP1 is nearly ready.

The complete list of fixed issues is on our issue tracker. Half a dozen of bugs have been reported by the community, all of minor impact, which means that 1.0 RTM was already very stable. Here is the list of the most visible improvements:

  • Runtime performance improvements: Many of you have complained (yes) of poor runtime performance and I have to admin that they were right to a certain extend. A service pack was surely not the place to make great improvements, but I have found some points where little effort resulted in high effect:
    • OnMethodBoundaryAspect do not call “methodof” at each method invocation; this information is cached instead. That is, only if neither the method neither the type is generic! Alex Yakutin (dataobjects.net) measured that the call of “methodof” was the most important performance killer. It has been removed.
    • The same with OnFieldAccessAccess and “fieldof”.
    • OnMethodInvocationAspect has now its own and optimal implementation of DynamicInvoke. Microsoft’s implementation was shamefully slow since it all relied on reflection. PostSharp now emits optimal MSIL instruction so there is no reflection at all!
  • Side-by-side compatibility with the future PostSharp 1.5 CTP 2 due in a few days.
  • Breaking change: All PostSharp assemblies have now and will have version 1.0.0.0 (i.e. the build and revision numbers are always zero) and you need to require a specific version in Visual Studio. This was due to the SxS challenge with 1.5. It also means that you won’t need to recompile plug-ins for each reversion of PostSharp; it will be enough to do it for each minor version.
  • Some annoying problem with debugging experience has been fixed: sometimes the debugging cursor did not really follow the actual code!
  • Some less visible issues you can see in our issue tracker.

I repeat, this is not the SP1 yet, this is a pre-release. I need a hundred of you to try it and to report bugs (eventually), then I will promote it to the SP1 release and update the download page. And now, what everyone expects, the download link. Which one? Oh, there is none, sorry. You have to download revision 459 or higher from http://download.postsharp.org/builds/1.0/.

Happy PostSharping!

-gael

]]>
0
gael http://www.postsharp.org/ <![CDATA[MicroContainer: a dependency injection framework for… the .NET Micro Framework!]]> http://www.postsharp.org/blog/2008/10/microcontainer-a-dependency-injection-framework-for-the-net-micro-framework/ 2008-10-20T14:06:07Z 2008-10-20T14:06:07Z Szymon Pobiega has just released Micro Container Framework, a dependency injection framework targeting the .NET Micro Framework 3.0.

What does it have in common with PostSharp? Easy! Since this platform typically runs with very limited resource, performance is of paramount importance. There is definitively no time to resolve dependencies at runtime, and there is anyway no support for dynamic compilation.

The solution? Resolve dependencies at compile-time and inject them… using PostSharp! There is not even use of System.Reflection at runtime!

Check this out on CodePlex.

Congratulations Szymon and thank you for this great work!

-gael

]]>
0
gael http://www.postsharp.org/ <![CDATA[Static Proxies for NHibernate using PostSharp]]> http://www.postsharp.org/blog/2008/10/static-proxies-for-nhibernate-using-postsharp/ 2008-10-10T07:55:26Z 2008-10-10T07:55:26Z Ayende Rayen has just implemented ’static proxies’ for NHibernate using PostSharp.

NHibernate is a well-known O-R mapper. One of the features, lazy loading of properties, previously required you to make all properties virtual. The reason is that the properties were “enhanced” (understand: subclassed) at runtime using AOPish techniques. With PostSharp, Ayende now enables lazy loading even.

Ayende did the job in 4 hours:

The first thing that I have to say is wow Post Sharp rocks! And I mean that as someone who is doing AOP for a long while, and has implemented some not insignificant parts of Castle.DynamicProxy. Leaving aside the amount of power that it gives you, PostSharp simplicity is simply amazing, wow!

The feature is now pre-alpha only, but “it works”. For more info please refer to Ayende’s blog or contact him.

Happy PostSharping!

-gael

]]>
2