Pygmalions.Prism.Framework
1.3.0
dotnet add package Pygmalions.Prism.Framework --version 1.3.0
NuGet\Install-Package Pygmalions.Prism.Framework -Version 1.3.0
<PackageReference Include="Pygmalions.Prism.Framework" Version="1.3.0" />
paket add Pygmalions.Prism.Framework --version 1.3.0
#r "nuget: Pygmalions.Prism.Framework, 1.3.0"
// Install Pygmalions.Prism.Framework as a Cake Addin #addin nuget:?package=Pygmalions.Prism.Framework&version=1.3.0 // Install Pygmalions.Prism.Framework as a Cake Tool #tool nuget:?package=Pygmalions.Prism.Framework&version=1.3.0
Prism Framework
This framework provides a generator to generate proxy class which can override non-final virtual methods of base classes in run-time.
The generator is implemented with dynamic IL weaving via System.Reflection.Emit library. It is designed in plugin model, which allows users to easily extend its function.
How It Works
The proxy generator use Emit to generate dynamic class which is inherited from the class to proxy, so virtual methods will be override thus their behaviors can be modified.
Concepts
Generator
A proxy generator is modular class generator based on static-IL-weaving with System.Reflection.Emit
.
You write your own plugins to customize the generated proxy class, such as adding codes to proxied methods
and implementing more interfaces, etc.
ClassContext
A class context describe the class to proxy. It contains the dynamic class builder for the generator to use, and method contexts.
Class contexts are the basic unit for plugin to process. Plugins can do the most jobs with the dynamic class builder.
Initializer method is a special method which will be invoked by all constructors. Thus, you can write your initializing behavior in this method rather than every constructor.
MethodContext
Method contexts are used to shared method data among different plugins. Plugins can add code with delegates which will emit IL code with the ILGenerator. Those delegates will be invoked in sequence to generate the proxy method.
There are 3 stages of a method generation procedure:
- Before Invoking.
- Invoking the proxied method.
- After Invoking.
The 2nd stage is the code which will invoke the proxied method directly. A code context has many properties or fields to control or describe this behavior, for example, the local variable which stores the return value of the proxied method.
CodeContext
Code contexts contains many fields or properties associated with the method code generation procedure.
You can use Skipped
filed in the before-invoking stage to skip the invocation of the proxied method,
or Result
to set the return value of the invocation of the generated method, or, passing values
between delegates in different stages with Data
dictionary.
Result
field is a local variable builder which must be used in Emit context. The variable in it
will be overwrite by the 2nd stage (Invoking the proxied method), so you can access it in the 3rd stage,
or set a content to it and set Skipped
true in the 1st stage (Before-invoking) to skip the proxied method,
which is the 2nd stage.
Attention, no matter the 2nd stage is skipped or not, the 3rd stage (After-invoking) will always be executed.
But codes in 3rd stage can access the Skipped
to check whether the proxied method is skipped or not.
Plugin
A plugin must implement IProxyPlugin
interface and be marked with one or more TriggerBy
attribute.
Then the Modify(ClassContext)
method will be invoked if the proxied class triggers this plugin.
A plugin can be triggered in 3 ways:
- By attributes marked on the proxied class.
- By attributes marked on members of the proxied class.
- By its parent or ancestor classes or interfaces which is implemented by this class.
A TriggerBy
attribute can declare a trigger type for this plugin.
In ByAttribute
mode, the plugin will be triggered by attributes which is assignable to the trigger type.
In ByHierarchy
mode, the plugin will be triggered by proxied classes which is assignable to the trigger type.
Best Practices
We recommend your plugins to use interfaces as triggers, and you can provide some basic attribute classes implementing those interfaces. In this way, users can define a custom attribute to trigger multiple plugins.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Pygmalions.Prism.Framework:
Package | Downloads |
---|---|
Pygmalions.Prism.Injecting
This plugin provides a mechanism to do proactive dependency injection, which means the object to inject proactively get the injection content from the container. |
|
Pygmalions.Prism.Remoting
This plugin provides a mechnaism to encode and decode invocation contexts to support RPC. |
|
Pygmalions.Prism.Decorating
This plugin provides a mechanism to modify the behavior of functions in run-time. |
GitHub repositories
This package is not used by any popular GitHub repositories.