Code Monkey home page Code Monkey logo

adepin's Introduction

ADepIn makefile workflow status

A dependency injector and small utilities used by it, made to be used by frameworks and their modules.

Contents

  1. Examples
    1.1. Getter calls
    1.2. Fluent binding calls
    1.3. Direct binding calls
  2. Notable Features

Examples

Getter calls

using ADepIn;

// Assign information to pass to the binding
IMyContext context = ...;

// Try to get implementations of the service given a context (#1) and given no context (#2)
Option<IMyService> implContextfulOpt = kernel.Get<IMyService, IMyContext>(context);
Option<IMyService> implContextlessOpt = kernel.Get<IMyService>();

// Gets the implementations
// These calls will throw if they do not exist
IMyService implContextful = implContextfulOpt.Unwrap();
IMyService implContextless = implContextlessOpt.Unwrap();

// Checks if the implementations exist, and if they do, does something
// Similar to Try* methods
if (implContextfulOpt.MatchSome(out IMyService implContextful))
{
  ...
}
if (implContextfulOpt.MatchSome(out IMyService implContextless))
{
  ...
}

Fluent binding calls

Fluent is the easy and recommended way to bind. In fact, it even makes the bindings for you!

using ADepIn;
using ADepIn.Impl; // for ADepIn.Impl.StandardServiceKernel only
using ADepIn.Fluent;

// Create something to hold bindings (service implementations)
IServiceKernel kernel = new StandardServiceKernel();

// Creates a contextless binding stub for IMyService
// To make a contextful stub, simply use kernel.Bind<IMyService, IMyContext>()
kernel.Bind<IMyService>()
  // "To" tells the stub how to make the service
  // PureNopMethod takes no inputs and outputs just the service, no-option (hence Nop)
  .ToPureNopMethod(() => ...)
  // "In" applies the stub, and may apply final modifiers
  // Transient has no modifiers; it will run the "To" every time
  .InTransientScope();

Direct binding calls

Direct binding is simple, yet inflexible. This is how the library fundamentally works.

using ADepIn;
using ADepIn.Impl; // for ADepIn.Impl.StandardServiceKernel only

// Create something to hold bindings (service implementations)
IServiceKernel kernel = new StandardServiceKernel();

// Assign bindings which take a context (#1) and take no context (#2) to create a service
IServiceBinding<IMyService, IMyContext> bindingContextful = ...;
IServiceBinding<IMyService, Unit> bindingContextless = ...;

// Add the bindings to the kernel
kernel.Bind(bindingContextful);
kernel.Bind(bindingContextless);

Notable Features

Why use yet another dependency injection library?

  • Infrequent exceptions
    • Some Argument...Exceptions, largely from non-nullable public APIs
    • A few InvalidOperationExceptions
    • Rarely NullReferenceExceptions (see Preventing NullReferenceExceptions)
  • Near-zero reflection
    • Some is used for entry module loading
    • Absolutely no System.Reflection.Emit (SRE)
  • Module system
    • IModule for modules that are manually constructed and loaded
    • IEntryModule<TSelf> for modules that are to be reflectively discovered and loaded
  • Publicly accessible utilities
    • Guard is an API helper class that asserts arguments
    • Option<T> is a discriminated union implementation of an option type, heavily based off of Rust's std::option
    • Unit is an empty readonly struct implementation of a unit type

Preventing NullReferenceExceptions

NullReferenceExceptions are few and far between within ADepIn because of C# 8.0's non-nullable reference types, null guards on reference types, and support for Option<T>. However, it has a weak spot in generics. Without a boxing call or possible reflection call in every null check, it is impossible to guarantee a generic type is not null. Therefore, if ADepIn receives a null value within a non-null generic parameter, ADepIn will not throw an ArgumentNullException.
For example:

using ADepIn;
using ADepIn.Impl;
using ADepIn.Fluent;

IServiceKernel kernel = new StandardServiceKernel();

kernel.Bind<IMyService>()
  .ToConstant(null); // null is being passed as TValue (IMyService), no null check is performed

...

// Neither of these throw because the kernel has no problem finding the binding and the binding returns Some
Option<IMyService> implOpt = kernel.Get<IMyService>();
IMyService impl = implOpt.Unwrap();

// Throws NullReferenceException
impl.DoThing();

The first (and easiest) approach is to target netcoreapp3.0 if your project permits it. Not to release the binaries, but to utilize the nullable static analysis.
The second way to combat this is to never use the null keyword. Get into the habit of using Option<T>, which explicitly states that there might not be a value. Be aware that code you call might return a null value still.

adepin's People

Contributors

malicean avatar

Watchers

 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.