Skip to content
This repository has been archived by the owner on Jan 16, 2022. It is now read-only.

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
Add badges
Clarify Step 0: Verification
Replace Options/Restrictions and FAQ with Documentation
  • Loading branch information
Abrynos committed Aug 21, 2021
1 parent 702c2c9 commit 1bbd344
Showing 1 changed file with 33 additions and 51 deletions.
84 changes: 33 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Implement.Net

[![CI status](https://img.shields.io/github/workflow/status/Abrynos/Implement.Net/CI?label=Build&logo=GitHub)](https://github.com/Abrynos/Implement.Net/actions/workflows/ci.yml)
[![Test status](https://img.shields.io/github/workflow/status/Abrynos/Implement.Net/CI?label=Tests&logo=GitHub)](https://github.com/Abrynos/Implement.Net/actions/workflows/ci.yml)
[![GitHub last commit](https://img.shields.io/github/last-commit/Abrynos/Implement.Net?label=Updated&logo=GitHub)](https://github.com/Abrynos/Implement.Net/commits)
[![open issues](https://img.shields.io/github/issues/Abrynos/Implement.Net?label=Issues&logo=GitHub)](https://github.com/Abrynos/Implement.Net/issues)
[![open merge requests](https://img.shields.io/github/issues-pr/Abrynos/Implement.Net?label=Merge%20requests&logo=GitHub)](https://github.com/Abrynos/Implement.Net/pulls)

[![dotnet version](https://img.shields.io/badge/Version-net5.0-brightgreen?logo=csharp)](https://dotnet.microsoft.com/download/dotnet/5.0)
[![license](https://img.shields.io/github/license/Abrynos/Implement.Net?label=License)](https://github.com/Abrynos/Implement.Net/blob/master/LICENSE.txt)

[![GitHub release date](https://img.shields.io/github/release-date/Abrynos/Implement.Net?label=Release&logo=GitHub)](https://github.com/Abrynos/Implement.Net/releases)
[![GitHub release](https://img.shields.io/github/v/release/Abrynos/Implement.Net?label=GitHub&logo=GitHub)](https://github.com/Abrynos/Implement.Net/releases)
[![Nuget](https://img.shields.io/nuget/v/Implement.Net?label=NuGet&logo=NuGet)](https://www.nuget.org/packages/Implement.Net)

## Description

Implement.Net is a C# library with the primary purpose of implementing interfaces at runtime by forwarding calls to their members to a statically typed handler.
Expand All @@ -10,9 +23,20 @@ Implement.Net is a C# library with the primary purpose of implementing interface

Make sure this is what you need. There is a very limited amount of actual use cases for this and you might be better off using something else.

### Step 1: Dependency
#### When should I (not) use this library?

- When you control what will be implemented (e.g. you want a method called `MultiplyWithTwo` that works for all numeric types) you have following possibilities:
- Use `dynamic` - This is a bad idea with a lot of runtime overhead, but it will work.
- Manually implement the method for all numeric types, since a generic version using the multiplication operator won't compile - This works but you'll have to copy the code a bunch of times.
- Implement the generic method `T MutliplyWithTwo<T>(T t);` using the `System.Linq.Expressions` namespace and compiled expressions - You should definitely go with this!
- When you **can't** control what will be implemented (You create a library with a few attributes the user can put on their own interface and you are expected to return an instance of said interface; e.g. you want to create the dotnet equivalent of [OpenFeign](https://github.com/OpenFeign/feign)):
- You can **not** use [Moq](https://github.com/moq/moq4), since that would require you to know the methods and properties in advance for calls like `mock.Setup(foo => foo.TheMethodYouDontKnowAbout()).Throws<Exception>();`.
- You force the users of your library to use `dynamic` and you go by name and arguments of whatever they call - Apart from the runtime overhead of `dynamic` they have no possibility of fine-tuning the behaviour of your implementation via e.g. attributes.
- You use this library - This statically binds everything, gives you access to reflection (including attributes) and even handles `IDisposable` for you.

### Step 1: Installation

From the command line add the dependency to your project:
From the command line add the [NuGet package](https://www.nuget.org/packages/Implement.Net) to your project:

```bash
dotnet add package Implement.Net
Expand All @@ -21,12 +45,12 @@ dotnet add package Implement.Net
Alternatively you can edit your `.csproj` file directly. Just make sure you replace the `*` from the example below with the version you want to use:

```xml
<ItemGroup>
<PackageReference Include="Implement.Net" Version="*" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Implement.Net" Version="*"/>
</ItemGroup>
```

In addition to the official NuGet registry we also push to [GitHub packages](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry).
In addition to the official package registry on [nuget.org](https://nuget.org/) we also push to [GitHub packages](https://github.com/Abrynos/Implement.Net/packages/932196).

### Step 2: Handler implementation

Expand Down Expand Up @@ -87,50 +111,8 @@ instance.SomeValue = 42;

To find out about all the configuration options and method overloads you have, you can once again visit our documentation.

## Options and Restrictions

We have extensive documentation in form of XML-comments in our source code. These are also included in our NuGet package and should be available in your IDE. We invite you to open a discussion in our GitHub repository if anything is unclear. Please be aware that discussions are different from issues. Issues are purely for development purposes, such as feature requests and bug reports. Incorrect use will get them closed with a canned response in no time at all.

There are several pre-conditions that must be met for type-generation to succeed. Most notably are the need for the interface to be `public` and the prohibition of unbound generic methods within it.

Here are some examples of what will or will not work:

```c#
public interface MySecondInterface<TInterfaceParameter> {
// This will work
TInterfaceParameter SomeProperty { get; }

// This will work as well
TInterfaceParameter SomeMethod(TInterfaceParameter m);

// Even this will work
delegate TInterfaceParameter SomeDelegate(TInterfaceParameter m);
event SomeDelegate SomeEvent;

// This will fail
void SomeMethod<TMethodParameter>(TMethodParameter p);
}
```

```c#
// This will not work - The interface has to be public
internal interface MyThirdInterface { }
```

```c#
TypeFactory typeFactory = new ();
// This will work
typeFactory.CreateType(typeof(SomeGenericInterface<int>));
// This will fail - There are unbound generic parameters
typeFactory.CreateType(typeof(SomeGenericInterface<>));
// This will fail - You can derive from it tho
typeFactory.CreateType(typeof(IDisposable));
// This will fail - TypeFactory is not an interface
typeFactory.CreateType(typeof(TypeFactory));
```

## FAQ
## Documentation

### What's the difference between this and the `dynamic` keyword?
We have extensive documentation in form of XML-comments in our source code. These are also included in our NuGet package and should be available in your IDE.

This allows for static typing. The "end user" can use a predefined interface instead of `dynamic`.
We invite you to open a [discussion](https://github.com/Abrynos/Implement.Net/discussions) in our GitHub repository if anything is unclear. Please be aware that discussions are different from issues. Issues are purely for development purposes, such as feature requests and bug reports. Incorrect use will get them closed with a canned response in no time at all.

0 comments on commit 1bbd344

Please sign in to comment.