Git Product home page Git Product logo

plugly's Introduction

Plugly

Plugly is a framework to alter behavior of existing .NET classes without a direct inheritance and method overrides. The framework is built on top of Castle.Core library and is using DynamicProxy interceptors to extend the methods behavior and mixins to implement additional interfaces and add extra properties to existing classes.

The integrations to some popular Inversion-of-Control containers are supported out of the box.

Table of contents:

Installation

Just install the corresponding NuGet package:

PM> Install-Package Plugly

All assemblies are signed.

Basic usage

Lets imagine that there is some class representing a customer:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    
    public virtual string GetFullName()
    {
        return LastName + ", " + FirstName;
    }
}

Notice, that the class is not sealed and GetFullName method is virtual, otherwise it could not be customized.

Now, we create an extension which alters the behavior of the GetFullName method:

Customizer.Current.Setup<Customer>()
    .Override<string>(c => c.GetFullName(), c => c.FirstName + " " + c.LastName)
    ;

After that, the customer instances should be created in the next way:

var customer = Customizer.Current.CreateInstance<Customer>();
customer.FirstName = "John";
customer.LastName = "Doe";
Debug.Assert(customer.GetFullName() == "John Doe");

Advanced example with a mixin

Below is an advanced customization scenario example which also demonstrates the support of mixins and object initializers. The following code extends the existing Customer class by appending a MiddleName property and including it in the output of the GetFullName method. Additionally, the following example demonstrates the possibility to add extra initialization of new class instances.

public interface IMyExtension
{
    string MiddleName { get; set; }
}

class MyExtension : IMyExtension
{
    public string MiddleName { get; set; }
    
// customization methods must be static, accept the target object as a first argument and be marked with a CustomizationAttribute
    [Customization]
    static void __init(Customer customer) // '__init' is a special name for object initializer
    {
        customer.FirstName = "noname";
    }
    
    [Customization]
    static string GetFullName(Customer customer)
    {
        var ext = (IMyExtension)customer;
        var fullName = customer.GetFullName(); // invokes the inner customization or an original method
        if (ext.MiddleName != null)
            fullName = fullName.Replace(" ", " " + ext.MiddleName + " ");
        return fullName;
    }
}

Then the above extension is plugged-in this way:

Customizer.Current.Setup<Customer>()
    .Override<string>(c => c.GetFullName(), c => c.FirstName + " " + c.LastName)
    .ExtendWith<MyExtension>()
    .InitializeWith(c => c.LastName = "unknown");

And here is the usage example:

var customer = Customizer.Current.CreateInstance<Customer>();
dynamic dynamicCustomer = customer;
dynamicCustomer.MiddleName = "midname";
Debug.Assert(customer.GetFullName() == "noname midname unknown");

Notice, that:

  1. Both initializers are invoked in the order they have been registered (both the FirstName and LastName properties are initialized with default values).
  2. Both customizations for GetFullName method are applied in the reverse order as they have been registered.

For all available features, possibilities and usage examples take a look at the unit-tests project.

Integration

Unity Container

Unity Container integration is enabled by:

1. Install the corresponding NuGet package

PM> Install-Package Plugly.Unity

2. Add the Plugly Unity extension

var container = new UnityContainer();
container.AddNewExtension<Plugly.Unity.Extension>();

3. Use the customizer

Customizer.Current
    .Setup<Customer>()
    .ExtendWith<CustomerExtension>();

Autofac

1. Install the corresponding NuGet package

PM> Install-Package Plugly.Autofac

2. Enable Plugly customizations on Autofac container

var builder = new ContainerBuilder();
// configure container
var container = builder.Build().EnableCustomizations();

StructureMap

Coming soon...

Other

If you need the integration with any other IoC container, just let me know and we will see what can be done.

Performance

The performance impact is very low due to staticly typed customizations. The exact numbers can be obtained by running the Plugly.Performance console app included in the solution.

Copyright

Copyright © 2015 Dmytro Moskalyk

License

The project is licensed under the MIT license.

plugly's People

Contributors

dmoskalyk avatar

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.