Shimterface.Standard
1.6.9
Shimterface has now been renamed to Shimr
dotnet add package Shimterface.Standard --version 1.6.9
NuGet\Install-Package Shimterface.Standard -Version 1.6.9
<PackageReference Include="Shimterface.Standard" Version="1.6.9" />
<PackageVersion Include="Shimterface.Standard" Version="1.6.9" />
<PackageReference Include="Shimterface.Standard" />
paket add Shimterface.Standard --version 1.6.9
#r "nuget: Shimterface.Standard, 1.6.9"
#:package Shimterface.Standard@1.6.9
#addin nuget:?package=Shimterface.Standard&version=1.6.9
#tool nuget:?package=Shimterface.Standard&version=1.6.9
Shimterface
Utility for creating a dynamic object facade/proxy to allow for using an object as an interface that it does not explicitly implement.
Description
I'm sure we've all been in the situation where we've had to make use of a class from an external library (including mscorlib) that either doesn't implement any interface or doesn't implement one that can be used for any kind of Inversion of Control usage. One approach is to implement a series of proxy objects that handle all of the required functionality, including proxies around returned values, and this can even be scripted (Powershell, T4, etc.) to prevent the arduous task of proxying every class you need.
You might also be frustrated that classes can't have an identical interface applied to them post-design. e.g.,
public class TestClass {
public void Test() {
...
}
}
public interface ITest {
void Test();
}
ITest forcedCast = (ITest)new TestClass();
Given that TestClass
implements all of ITest
members, logically this would be a lovely language feature. Instead, we get a runtime InvalidCastException
.
Shimterface solves and takes the effort out of this problem by compiling dynamic proxies to convert classes to the requested interface. The above example can be fixed using Shimterface by doing:
ITest forcedCast = new TestClass().Shim<ITest>();
If you ever needed the original back again, then you simply unshim it:
TestClass originalObject = ShimBuilder.Unshim<TestClass>(forcedCast);
The wiki contains lots more examples and detailed coverage of usage.
Breaking changes
See the breaking change wiki.
Design principal
The purpose of Shimterface is to improve testability and inversion-of-control; therefore, all behavioural decisions are designed to be implemented as application design-time. This is not a mocking library.
Outside of setting up your DI/IOC container and facades, if you're referencing Shimterface directly, it's likely that you're thinking about a different problem domain to the one solved by this library.
Known Issues
- If the compilation of the proxy type fails but the application handles it, the Type-Interface combination is now not usable
Future Ideas
- Generate assembly of compiled shims for direct reference
- Combine multiple target types to single shim
- Behavioural configuration to attributes (e.g., [Shim(IgnoreMissingMembers = true)])
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- System.Reflection.Emit (>= 4.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
[v.1.6.9] New namespace for extension methods
[v.1.6.8] Fixed issue #19 - Exception shimming certain method overrides
[v1.6.7] Fixed issue #17 - .NET 6 support for constructors on generic types
[v1.6.6] Fixed issue #16 - invalid shim for multiple args to generic type constructor
[v1.6.5] Generic method can be used to construct a generic type (Issue #14)