Generic WeakReference proxy - c#

I want to create custom WeakReference<T> which would implement an interface passed as generic parameter T.
Usage:
interface IInterface
{
void SomeMethod(bool param);
}
public class Subject : IInterface { /*...*/ }
var proxyRef = new ProxyWeakReference<IInterface>(new Subject());
proxyRef.SomeMethod(false);
IInterface subject = proxyRef.Target;
Is there any already created solutions to do that? Or what i should use to create such type of proxy?

Probably, You are looking for a Moq

Related

Moq - How to create a mock that implements multiple interfaces at the same time [duplicate]

Here's my class implementation where the generic is implementing two interfaces...
public class ClassA<TGeneric> : where TGeneric: IInterfaceA, IInterfaceB
I want to Mock ClassA. However, I can't use
var mock = new Mock<Class<A<IInterfaceA>>();
or
var mock = new Mock<Class<A<IInterfaceB>>();
since the generic requires implementations of both interfaces. I know you can mock objects with multiple interfaces by using the As() method on the moq, but I don't really have an object here but a generic type.
Thoughts?
Thanks...
You could define an interface that includes both interface A and B (in your test project, for testing purposes), then use that in your mock.
public interface ICanTestAAndB : IInterfaceA, IInterfaceB {}
var mock = new Mock<ClassA<ICanTestAAndB>>();
As alternative to the accepted answer you can achieve what you need by casting the mocked object to dynamic and at runtime it will work as expected.
void Main()
{
var mockA = new Mock<IIntA>();
mockA.Setup(a => a.DoA()).Returns(3);
var mockB = mockA.As<IIntB>();
mockB.Setup(iib => iib.DoB()).Returns(7);
dynamic d = mockB.Object;
TakeBoth(d);
}
void TakeBoth<T>(T obj) where T : IIntA, IIntB
{
}
public interface IIntA { int DoA(); }
public interface IIntB { int DoB(); }

.NET Core Cast to interface with generic type parameter of type which implements interface

In .NET Core C#
I' trying something like this:
(IInterface<IParameter>)instance
Where instance is new Implementation<Parameter>()
And Implementation : IInterface & Parameter : IParameter
The issue is with the casting of the generic parameter. When I provide Parameter instead of IParameter it works but at compile time there is no way to know which type that implements IParameter will be used. All of these objects will be created via reflection.
So is there any way this cast works? Or some other way to implement this like providing no generic type parameter like you can with typeof.
EDIT Thanks to Ziriax
A Fully Working Example:
interface IInterface
{
void Run(TInput input);
}
abstract class AbstractClass<TInput> : IInterface
where TInput : IParameter
{
public abstract void Execute(TInput input);
public void Run(IParameter input)
{
Execute((TInput)input);
}
}
interface IParameter {}
class Implementation : AbstractClass<Parameter>
{
public void Run(Parameter input)
{
}
}
class Parameter : IParameter {}
class Program
{
static void Main()
{
object instance = new Implementation();
var castInstance = (IInterface) instance;
castInstance.Run(new Parameter());
}
}
Why don't you add a non-generic interface too:
interface IInterface
{
void Run(IParameter input);
}
And then let your generic interface extend this non-generic one.
Obviously your implementations should cast the IParameter, someone needs to cast it... You could make an abstract base class that does this for you, so not every implementation has to do this.
You might also be interested in the double dispatch pattern, although I'm not sure this will work in your case.
As you have it now, this cannot work. Your Implementation class implements IInterface<Parameter>, so its Run method only accepts a parameter of the concrete Parameter type, whereas the IInterface<IParameter> requires that its Run method accepts an instance of any type that implements IParameter.
If the type of cast you're trying to do were allowed, I could define a different class that implements IParameter, e.g.:
public class DifferentParameter : IParameter { ... }
And then do:
castInstance.Run(new DifferentParameter());
But your Implementation's Run method can't take DifferentParameter!
.NET therefore prevents you from performing the cast itself.
There are situations in which this kind of cast is allowed - if your interface were instead to be defined as:
interface IInterface<out TOutput>
where TOutput : IResult
{
TOutput Run();
}
By making the generic parameter out, it makes the interface covariant. This restricts the use of the type parameter as the result of method calls, but for covariant interfaces, casts like yours are allowed.
You can find plenty of documentation on both covariance and contravariance in the .NET documentation.

Using generics in interfaces in C#

I have an app written in C#. My app has a class that looks like the following:
public class FinderA
{
public IEnumerable<FinderA> GetItems()
{
return FinderA.FindAll();
}
}
I want to require other classes to do something similar. I cannot use a base class because my actual implementation is already using a base class. For that reason, I want to create an interface. Currently, I'm trying the following:
public interface IFinder
{
IEnumerable<T> GetItems();
}
When I use this approach, I get a compile-time error that says: "The type or namespace name 'T' could not be found (are you missing...". To overcome this, I add <T> to the end of the interface name so it looks like this:
public interface IFinder<T>
{
IEnumerable<T> GetItems();
}
This is turn generates another compile-time error that says: "Using the generic type 'IFinder' requires 1 type arguments.". My challenge is, I want the interface to be generic. I do not want to pass in a type. Is there a way around this? If so, what/how?
There is no way around this; you'll need to actually supply the generic type argument when declaring that a class implements the interface.
You can do this at the method level instead of as a generic type on the interface itself.
public interface IFinder
{
IEnumerable<T> GetItems<T>();
}
Your code can then call it like such:
IFinder finder = // Create finder instance
IEnumerable<MyClass> discoveredClasses = finder.GetItems<MyClass>();
If you want to ensure that MyClass is a class that implements IFinder, you can constrain the method.
public interface IFinder
{
IEnumerable<T> GetItems<T>() where T : IFinder;
}
That will cause the following to generate a compiler error:
public class Foo
{
}
public class Bar
{
Bar()
{
IFinder finder = // Create finder.
// This fails because <T> (Foo) does not implement IFinder.
IEnumerable<Foo> fooItems = finder.GetItems<Foo>();
}
}
but it will allow the following to compile
public class MyFinderA : IFinder
{
IEnumerable<T> GetItems<T>() where T : IFinder
{
return // Create collection of T
}
public class Bar
{
Bar()
{
IFinder finder = // Create finder.
// This works as <T> (MyFinderA) is an IFinder implementation
IEnumerable<MyFinderA> finderItems = finder.GetItems<MyFinderA>();
}
}
If you want your interface to be generic but you are not willing to supply a type argument, you can return an IEnumerable<object>.
public interface IFinder {
IEnumerable<object> GetItems();
}
All class types extend from System.Object so that should suffice for any type in your applicacion (enums and structs would get boxed)
Please note that this approach requires the interface's consumer to cast the generic object instances to the appropiate types.
The alternate (and recommended) approach is to make the interface use type parameters, but for that you must supply the appropiate type arguments

Castle dynamic proxy not creating an implementation for inherited interface method

I have a base interface that is inherited by several other interfaces. This interface has one method:
[ServiceContract]
public interface IBase
{
[OperationContract]
List<short> GetShorts();
}
I then, of course, have an inheriting interface:
[ServiceContract]
public interface IUseful : IBase
{
[OperationContract]
List<MyObject> GetMyObjects(MyInput input);
}
I have a class that serves as a generic interceptor for interfaces in order to provide a simple way to call services without extra setup:
public class ServiceInvoker<T> : DynamicObject, IInterceptor
where T : class
{
// ...
public T Client { get { return (dynamic)this; } }
// ...
}
I want to be able to call any service that implements IBase, so I have a class that looks like this:
public class BaseCaller
{
private readonly IBase _base;
public BaseCaller(IBase base) { _base = base; }
public List<short> GetShorts() { return _base.GetShorts(); }
}
I construct BaseCaller basically like this:
var si = new ServiceInvoker<IUseful>();
var bc = new BaseCaller(si.Client);
The problem comes when I make a call to GetShorts and it calls _base.GetShorts:
MissingMethodException
Method 'MyApp.IUseful.GetSubNumbers' not found.
When I hover over _base, I can see the interceptor, and I can see that token_GetSubNumbers exists. I can cast _base to IUseful and call GetMyObjects successfully; I just can't call GetShorts. It looks like Castle isn't implementing IBase. Am I doing something wrong?
This appears to work, so going with it unless someone provides a better solution:
I removed the inheritence of IBase and just use it directly with a ServiceInvoker<IBase>. The services now have to implement IBase directly and expose an endpoint for it, but it works.

Mocking generics that implement multiple interfaces

Here's my class implementation where the generic is implementing two interfaces...
public class ClassA<TGeneric> : where TGeneric: IInterfaceA, IInterfaceB
I want to Mock ClassA. However, I can't use
var mock = new Mock<Class<A<IInterfaceA>>();
or
var mock = new Mock<Class<A<IInterfaceB>>();
since the generic requires implementations of both interfaces. I know you can mock objects with multiple interfaces by using the As() method on the moq, but I don't really have an object here but a generic type.
Thoughts?
Thanks...
You could define an interface that includes both interface A and B (in your test project, for testing purposes), then use that in your mock.
public interface ICanTestAAndB : IInterfaceA, IInterfaceB {}
var mock = new Mock<ClassA<ICanTestAAndB>>();
As alternative to the accepted answer you can achieve what you need by casting the mocked object to dynamic and at runtime it will work as expected.
void Main()
{
var mockA = new Mock<IIntA>();
mockA.Setup(a => a.DoA()).Returns(3);
var mockB = mockA.As<IIntB>();
mockB.Setup(iib => iib.DoB()).Returns(7);
dynamic d = mockB.Object;
TakeBoth(d);
}
void TakeBoth<T>(T obj) where T : IIntA, IIntB
{
}
public interface IIntA { int DoA(); }
public interface IIntB { int DoB(); }

Categories

Resources