Repository navigation
PostSharp 2027.0.6-preview
Pre-release
Pre-release
PostSharp 2027.0.6-preview is based on v2027.0.5-preview, plus the following changes.
Highlights
- Dependency injection in aspects. An aspect can now receive a service from dependency injection: the target class gets the service as a constructor parameter, and the advices read it (#318).
[Cache]and[InvalidateCache]are the first aspects to use it: they can take theirICachingServicefrom the container instead of a process-wide static (#323). - Background compilation server for .NET. Until now, only .NET Framework projects were compiled in a background pipe server. With
dotnet build, .NET projects are now compiled in one too, on Windows, Linux and macOS, instead of in a newdotnet execprocess for each project (#322).
Aspect framework
- #316 New:
[ImportMember]can be applied to the parameters of an advice method, so that a statically scoped aspect can read and write the members of its target class without an instance-scoped aspect. The type of the parameter selects what the advice receives: the value or the address of a field (T,in T,ref T,out T), the value of a property, anILocationBinding<T>, an open delegate or anIMethodBindingfor a method, or aProperty<T>orEvent<T>in an instance-scoped aspect. Without a name, a field or property is matched by its type. - #317 New:
IntroduceFieldAdviceInstance, returned byIAdviceProvider.ProvideAdvices, introduces a field into the target class, so that a statically scoped aspect can keep per-object state in the target object. The request can reuse an existing field, which is how two aspects share a field, and the advices read the field with[ImportMember]. - #318 New:
ImportDependencyAdviceInstancelets an aspect receive a service from dependency injection. The target class gets a field and a constructor parameter of the service type, also pulled into its derived classes in the project, and the advices read the service with[ImportMember]. The original constructors are kept as non-public forwarders that resolve the service from the newRunTimeServiceLocator, sonewin the project still works. Applying such an aspect to a public class changes its public constructors. - #324 Enhancement: the advices of an aspect are grouped by the new
GroupingAdvice.Groupproperty, which names the group of an advice, whatever the class that declares it. WhenGroupis not set, an advice without a pointcut joins the group of its class that has no advice of its kind yet.Masterand[SelfPointcut]are obsolete (CS0618). A redundantGroupis reported as LA0255, two groups of one family that both apply to the target of the aspect as LA0257,GroupandMasteron one advice as LA0258, and two pointcuts in one group as LA0259.⚠️ Breaking change: several[SelfPointcut]advices of different kinds withoutMaster, such as an entry and an exit advice, now form one group instead of one group each, so they share theirMethodExecutionArgsandMethodExecutionTag. Builds that useTreatWarningsAsErrorsfail on the new warnings until the aspect is updated. - #325 Enhancement:
[OnMethodInvokeAsyncAdvice]now accepts the[Declaration],[DeclarationName],[DeclarationIdentifier],[Arguments],[Argument]and[Binding](asIAsyncMethodBinding) parameters, also in a generic advice method. The advice can return aTask<T>whose result becomes the result of the target; any other result type is reported as LA0287. - #328 Enhancement: set
MatchPointcut.IsRequiredtotrueto report LA0285 when the advice applies to no method, because no method has the name or no overload matches the advice. - #315 New:
ProjectLocal<T>stores build-time state per project, for state that an aspect or a build-time service kept in a static field and that therefore leaked from one project to another processed by the same process.
Compiler
- #322 New: with
dotnet build, PostSharp compiles a .NET project in a long-running pipe server of the current user, instead of starting adotnet execprocess for each project. The server runs several compilations at a time, each in its own assembly load context, on Windows, Linux and macOS. On a small solution, a warm server compiled a project in 0.2 to 0.3 s instead of about 1 s. SetPostSharpUsePipeServertoFalseto compile withdotnet execas before. Projects that target x86, and the MSBuild of Visual Studio, keepdotnet exec.postsharp shutdownalso stops these servers.⚠️ Breaking change: on by default. - #321 Fix: the compiler no longer shares its third-party dependencies, such as Newtonsoft.Json, System.Text.Json, System.Collections.Immutable or Microsoft.Extensions.DependencyInjection, with the project it compiles. On .NET Framework, a project that references a higher version of one of them no longer fails with PS0264, and the build-time code of a project runs against the versions that the project references.
⚠️ Breaking change: an add-in loaded with<Using>inPostSharp.configthat relied on the compiler to supply one of these assemblies must ship it beside the add-in.
PostSharp.Patterns.Caching
- #323 New: with
[CacheConfiguration( UseDependencyInjection = true )],[Cache]and[InvalidateCache]use anICachingServicethat the class receives from dependency injection, instead of the process-wideCachingServices.DefaultBackend, so each container has its own cache. Register the service with, for instance,services.AddSingleton<ICachingService>( new CachingService( backend ) ). Static methods and methods of structs fall back toCachingServices.DefaultServiceand are reported as CAC011, whose severityStaticMethodFallbackSeveritysets. Invalidating a method that uses the other service is CAC012.⚠️ Breaking change:CacheAttributeandInvalidateCacheAttributeare now sealed and derive fromMethodLevelAspectinstead ofMethodInterceptionAspect.CachingServices.DefaultBackend,DefaultKeyBuilder, someCachingServices.Invalidationoverloads and the nestedCachingServices.CachingProfileRegistryare obsolete; useCachingServices.DefaultService. An async iterator with[Cache]is now reported as CAC013 instead of LA0197.
PostSharp.Testing.AspectTesting
- #326 New: the
@CompareTransformedCodedirective decompiles the woven assembly to C# and compares the declarations marked with// <target>, or all the top-level types of the file, with a.t.cssnapshot next to the test, which is accepted like the other expected files.