Git Product home page Git Product logo

blur's Introduction

Blur

Blur uses Mono.Cecil to weave assemblies from the inside. To make this easier, Blur provides fluent APIs for IL generation and MethodDefinition invocation.

Warning

Blur has been deprecated in favor of Cometary, and more specifically its IL sample.

Five-minutes annotated guide

using System;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Blur;

// The only requirement when using Blur is to mark
// the assembly with the BlurAttribute.
// This attribute also exposes some useful settings.
// Here, the CleanUp property is set to true:
//  bool CleanUp { get; set; }
// In this case, all references to Mono.Cecil and Blur will
// be removed from the assembly, including all weavers
// and visitors.
[assembly: Blur(CleanUp = true)]

/// <summary>
/// Forces the marked method to block its execution before
/// returning.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
sealed class BlockMethodAttribute : Attribute, IMethodWeaver
{
    // The IMethodWeaver interface must be set on this attribute
    // to register it as a compile-time attribute.
    // Its only declaration is:
    //  void Apply(MethodDefinition)
    // There are other interfaces such as this one, for every element
    // that can be marked with an attribute, EXCEPT assemblies and modules.

    private readonly static MethodReference ReadLineMethod
        = typeof(Console).GetMethod(nameof(Console.ReadLine)).GetReference();

    /// <summary>
    /// Prepends <see cref="Console.ReadLine"/> before all
    /// <see langword="ret"/> op codes.
    /// </summary>
    public void Apply(MethodDefinition method)
    {
        // The ILWriter is the class used by Blur users to edit methods.
        // It provides a Fluent API, and the ability to inject non-IL code,
        // such as LINQ Expressions and delegates, directly into bodies.
        //
        // The ILWriter can be obtained with 4 methods:
        //  ILWriter Write(this MethodBody body)
        //  ILWriter Write(this MethodDefinition method)
        //  ILWriter Rewrite(this MethodBody body)
        //  ILWriter Rewrite(this MethodDefinition method)
        //
        // Using Rewrite() will reset the method's body.
        ILWriter writer = method.Write();

        // Iterate over every instruction in the method's body.
        // If the body is changed during an iteration, the
        // current position of the ILWriter (obtainable with the
        // ILWriter.Position property) will be automatically updated.
        writer.ForEach(ins =>
        {
            // If the opcode of the instruction is "ret", ...
            // For those of you that are not familiar with IL, "ret" is
            // the opcode that corresponds to "return the value at the top of the stack".
            if (ins.OpCode == OpCodes.Ret)
                // ILWriter's fluent API chains calls together.
                // The following expression will write the following IL code:
                //  call    string [mscorlib]System.Console::ReadLine()
                //  pop
                // Note that Call() automatically inserts 'this' if the method is
                // an instance method, and uses Callvirt if needed.
                writer
                    .Before(ins)            // Position writer before the given instruction
                    .Call(ReadLineMethod)   //  call string [mscorlib]System.Console::ReadLine()
                    .Pop();                 //  pop
        });
    }
}

class Program
{
    [BlockMethod]
    public static void Main(string[] args)
    {
        Console.WriteLine("Hopefully, you will have time to see this message...");
    }
}

How to install

Install-Package Blur -Pre

Currently compatible with:

  • .NET Standard 1.3 and over.
  • .NET 4.5 PCL and over.

Features

ILWriter

The ILWriter class provides fluent methods meant to make editing IL easy. IL can be emitted:

  • Using delegates (via ILWriter.Delegate(delegate)).
  • Using LINQ Expressions (via ILWriter.Expression(Expression)).
  • Using a simplified emitter.
  • Using raw IL (via ILWriter.Emit(OpCode, ...) and Blur.Extensions.ILWriterExtensions).

BlurVisitor

The BlurVisitor provides many methods that will be called whenever a declaration is about to or has been modified by Blur:

  • void Visit(TypeDefinition type)
  • void Visit(FieldDefinition field)
  • void Visit(MethodDefinition method)
  • ...

Any class that inherits BlurVisitor and is in BlurAttribute.Visitors will automatically be created and used when weaving an assembly.

In-Assembly weaving

  • The entire assembly is available to you during compilation.
  • Methods can be invoked at any time, even if they have been previously modified.
  • Placing a breakpoint in a IWeaver method is enough to debug the modification of your assembly.

Miscellaneous

  • Conversion helpers, adding the ability to convert from System.Reflection to Mono.Cecil, and vise-versa (via Blur.BlurExtensions).
  • Fully documented assembly, including every IL instruction.

blur's People

Contributors

6a avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

sebandraos

blur's Issues

Add Verify method

Add a Verify() method to the Processor. Right now, the only thing it would do is check if a pre-processed extern method still exists.

[Question/Issue] Blur in .NetStandard class library

Hi,

I'm testing this as a .NetStandard compatible alternative to Fody but I'm coming up against some issues when referencing Blur 0.2.9-beta in a .NetStandard1.3 library. Is this indeed compatible with .NetStandard? If so, what is the appropriate setup? I am currently creating a file in my project and using it as an attribute, although I am planning on testing the Visitor pattern once this works. If this is not the right way, what is the correct setup for the targets etc.

Everything appears to be in place and I have copied the attribute setup as demonstrated in the readme but upon building I receive:
Severity Code Description Project File Line Suppression State Error CS2012 Cannot open 'd:\Documents\visual studio 2017\Projects\TestNetStandard\TestNetStandard\obj\Debug\netstandard1.3\TestNetStandard.pdb' for writing -- 'The process cannot access the file 'd:\Documents\visual studio 2017\Projects\TestNetStandard\TestNetStandard\obj\Debug\netstandard1.3\TestNetStandard.pdb' because it is being used by another process.' TestNetStandard d:\Documents\visual studio 2017\Projects\TestNetStandard\TestNetStandard\CSC 1 Active
Even if I change the Build Action of the attribute file (and remove references to it) to None, I get the same issue.
Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.