Multiple implementations of same grain interface using Orleans - c#

I have an Orleans applications with the following structure:
public interface IGraintest : Orleans.IGrainWithGuidCompoundKey
{
Task Init();
}
public abstract class GraintestImpl<T> : Grain, IGraintest, Deserializer<T>
{
string streamName;
public Task Init()
{
return Task.CompletedTask;
}
public override async Task OnActivateAsync()
{
var primaryKey = this.GetPrimaryKey(out streamName);
var streamProvider = GetStreamProvider("SMSProvider");
var stream = streamProvider.GetStream<String>(primaryKey, streamName);
// To resume stream in case of stream deactivation
var subscriptionHandles = await stream.GetAllSubscriptionHandles();
if (subscriptionHandles.Count > 0)
{
foreach (var subscriptionHandle in subscriptionHandles)
{
await subscriptionHandle.ResumeAsync(OnNextMessage);
}
}
await stream.SubscribeAsync(OnNextMessage);
}
public abstract T Process(string l);
private Task OnNextMessage(string message, StreamSequenceToken sequenceToken)
{
T obj = Process(message);
//gonna do something with obj here
return Task.CompletedTask;
}
}
public class ProcessImplA: GraintestImpl<Car>
{
public override Car Process(string l)
{
return new Car(l);
}
}
public class ProcessImplB: GraintestImpl<Boat>
{
public override Boat Process(string l)
{
return new Boat(l);
}
}
Here I have a grain that I use to read messages from a stream and apply some operation to them. Since I have different object types I want to work with I created an abstract class to implement the interface.
The problem lies here:
var sourceOne = client.GetGrain<IGraintest>(guid, "Car");
var sourceTwo = client.GetGrain<IGraintest>(guid, "Boat");
When I run the program like this I get the error code:
Exception while trying to run client: Cannot resolve grain interface ID=-<blabla> to a grain class because of multiple implementations of it
So my question is, can I do a minor change to make this work or do I have to create a grain interface for each ProcessImpl grain that I want to utilize?

You can disambiguate the GetGrain call by using an overload which accepts a grain class name prefix.
var sourceOne = client.GetGrain<IGraintest>(guid, "Car", grainClassNamePrefix: "MyNamespace.ProcessImplA");
var sourceTwo = client.GetGrain<IGraintest>(guid, "Boat", grainClassNamePrefix: "MyNamespace.ProcessImplB");
Otherwise, if there are two implementations of the interface then the runtime does not know how to decide which one to use. Importantly for your case, the information about which class implements which constructed generic interface is not known to the IGrainFactory implementation, so it is not able to pick an implementation.
Another approach is to add a marker interface to your grain classes, for example, you could have IGrainTestImplBoat:
public interface IGrainTestImplBoat : Orleans.IGrainWithGuidCompoundKey { }
public class ProcessImplB : GraintestImpl<Boat>, IGrainTestImplBoat { /* ... */ }
var sourceTwo = client.GetGrain<IGrainTestImplBoat>(guid, "Boat");

Related

How to inject all classes implementing the same generic interface in the constructor using StructureMap?

I have a bunch of data fetchers which all has the almost same signature. The only thing that differs is the return type. The return type is specified as T:
I have this interface:
public interface IDataFetcher<T>
{
T FetchData(MyObject data);
}
Next I have a about 10 implementations of this interface. In de the calling code I want to do something like this:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<T>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<T>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}
So, in the end, what I want is not have to inject each DataFetcher<T> implementation in the constructor. I am looking for a way to retreive all the registrations of IDataFetcher<T> from StructureMap.
I am open for every other design that achieves the same result, ie, not inject each implementation in the constructor.
What we can do is introduce another interface for return type and all the types that will be returned will implement it.
Define an interface :
public interface IData
{
}
public interface IDataFetcher<T> where T : IData
{
T FetchData(MyObject data);
}
As an example a type that would be returned:
public class FooData : IData
{
}
and it's DataFetcher implementation will look like:
public class FooDataFetcher : IDataFetcher<FooData>
{
public FooData FetchData(MyObject data)
{
// logic here and return instance of FooData
}
}
Now what we can do is define the Handler class something like:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<IData>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<IData>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}

How to avoid casting to a specific interface

Background info
I have a set of interfaces/classes as follows. For the sake of simplicity imagine more properties, collections etc.
interface IMaster
{
//Some properties
}
interface IB : IMaster
{
string PropOnA { get; set }
}
interface IC : IMaster
{
string PropOnB { get; set }
}
class B : IB
class C : IC
...
These contracts were designed to store data(which is held in a slightly different format in each case). There is a lot of code that uses these contracts to get the data, format it, process it, write etc.
We have developed an entire library that does not see the concrete implementations(B,C) of any of these contracts by inverting control and allow the user to use our 'default implementations' for each contract or just loading in their own. We have registry where the user can register a different implementation.
To this end I have implemented a kind of strategy pattern where there exists a strategy for each contract type based on the task at hand. For the sake of simplicity lets say the task is writing, in reality it is much more complicated.
interface IWriteStrategy
{
public Write(IMaster thing);
}
class WriterA : IWriteStrategy
class WriterB : IWriteStrategy
etc
The above concrete strategies are also never 'seen' in our library, the client must register their own implementation or our default version.
Design flaw??
I am not liking the cast in every strategy that is now necessary.
public classWriterA : IWriteStrategy
{
public void Write(IMaster thing)
{
if(thing is IA thingA)
//do some work
}
}
public classWriterB : IWriteStrategy
{
public void Write(IMaster thing)
{
if(thing is IB thingB)
//do some work
}
}
What we want to do is be able to loop through a list of IMaster objects and run some operations.
foreach(var thing in Things)
{
var strategy = GetStrategy(thing.GetType()); //this gets the strategy object from our `registry` if one exists
strategy.Execute(thing);
}
The above design allows this but there seems to be a flaw which I cant for the life of me spot a solution to. We have to cast to the specific interface within each strategy implementation.
I have tried with generics, but just cant seem to nail it.
Question
What would be a better way of designing this to avoid the cast but still be able to loop through a list of IMaster things and treat them the same? Or is the cast absolutely necessary here?
I am trying to follow a SOLID design but feel the cast is messing with this as the client implementing the strategies will have to do the cast in order to get anything to work within the Write method.
[Edit]
I have updated the classes implementing the IWriteStrategy.
If you rarely add new IMaster specializations, but often add new operations OR need to make sure operation providers (e.g writer) needs to support ALL specializations then the Visitor Pattern is a perfect fit.
Otherwise you basically need some kind of service locator & registration protocol to map operation providers/strategies to IMaster specializations.
One way you could do it is define generic interfaces such as IMasterWriter<T> where T:IMaster which can then be implemented like IBWriter : IMasterWriter<IB> which defines the mapping.
From that point you only need a mechanism that uses reflection to find a specific IMasterWriter implementor for a given type of IMaster and decide what to do if it's missing. You could scan assemblies early to detect missing implementations at boot rather than failing later too.
Maybe it is appropriate to use Strategy pattern and just give an implementation and execute it. Let me show an example.
interface IMaster
{
void ExecuteMaster();
}
class MasterOne : IMaster
{
public void ExecuteMaster()
{
Console.WriteLine("Master One");
}
}
class MasterTwo : IMaster
{
public void ExecuteMaster()
{
Console.WriteLine("Master Two");
}
}
and
interface IWriteStrategy
{
void Write(IMaster thing);
}
class WriterA : IWriteStrategy
{
public void Write(IMaster thing)
{
Console.WriteLine("Writer A");
thing.ExecuteMaster();
}
}
class WriterB : IWriteStrategy
{
public void Write(IMaster thing)
{
Console.WriteLine("Writer B");
thing.ExecuteMaster();
}
}
and code to execute:
static void Main(string[] args)
{
List<IWriteStrategy> writeStrategies = new List<IWriteStrategy>()
{
new WriterA(),
new WriterB()
};
List<IMaster> executes = new List<IMaster>()
{
new MasterOne(),
new MasterTwo()
};
for (int i = 0; i < writeStrategies.Count(); i++)
{
writeStrategies[i].Write(executes[i]);
}
}
what about this, you will have all your casts in one strategy factory method:
public interface IWriterStrategy
{
void Execute();
}
public class WriterA : IWriterStrategy
{
private readonly IA _thing;
public WriterA(IA thing)
{
_thing = thing;
}
public void Execute()
{
Console.WriteLine(_thing.PropOnA);
}
}
public class WriterB : IWriterStrategy
{
private readonly IB _thing;
public WriterB(IB thing)
{
_thing = thing;
}
public void Execute()
{
Console.WriteLine(_thing.PropOnB);
}
}
public static class WriterFactory
{
public static List<(Type Master, Type Writer)> RegisteredWriters = new List<(Type Master, Type Writer)>
{
(typeof(IA), typeof(WriterA)),
(typeof(IB), typeof(WriterB))
};
public static IWriterStrategy GetStrategy(IMaster thing)
{
(Type Master, Type Writer) writerTypeItem = RegisteredWriters.Find(x => x.Master.IsAssignableFrom(thing.GetType()));
if (writerTypeItem.Master != null)
{
return (IWriterStrategy)Activator.CreateInstance(writerTypeItem.Writer, thing);
}
throw new Exception("Strategy not found!");
}
}
public interface IMaster
{
//Some properties
}
public interface IA : IMaster
{
string PropOnA { get; set; }
}
public interface IB : IMaster
{
string PropOnB { get; set; }
}
public interface IC : IMaster
{
string PropOnC { get; set; }
}
public class ThingB : IB
{
public string PropOnB { get => "IB"; set => throw new NotImplementedException(); }
}
public class ThingA : IA
{
public string PropOnA { get => "IA"; set => throw new NotImplementedException(); }
}
public class ThingC : IC
{
public string PropOnC { get => "IC"; set => throw new NotImplementedException(); }
}
internal static class Program
{
private static void Main(string[] args)
{
var things = new List<IMaster> {
new ThingA(),
new ThingB()//,
//new ThingC()
};
foreach (var thing in things)
{
var strategy = WriterFactory.GetStrategy(thing); //this gets the strategy object from our `registry` if one exists
strategy.Execute();
}
}
}

Abstract class constructor call overridable method

I try to create a good testable repository class to use with Moq. I don't want duplicate my selector methods (GetAll, Get, ...). My implementation works fine but SonarSource reports an error RSPEC-1699 Does anyone know of a better implementation?
var areas = new Area[] { ... };
var areaRepositoryMock = new Mock<BaseAreaRepository>() { CallBase = true };
areaRepositoryMock.Setup(m => m.Initialize()).Returns(areas);
Base Class
public abstract class BaseAreaRepository
{
protected Area[] _areas;
protected BaseAreaRepository()
{
this._areas = this.Initialize();
}
public abstract Area[] Initialize();
public Area[] GetAll()
{
return this._monitoredAreas;
}
public Area Get(int id)
{
return this._areas.FirstOrDefault(o => o.Id.Equals(id));
}
}
MyAreaRepository
public class MyAreaRepository : BaseAreaRepository
{
public override Area[] Initialize()
{
return //Load data from an other source
}
}
The RSPEC-1699 Constructors should only call non-overridable methods doens't have anything with the unit tests it will remain there regardless how you are going to test it.
Does anyone know of a better implementation?
I would like to propose another approach in order to avoid this violation and make your code even more testable.
The idea is instead of the base class use composition and DI principle.
public interface IAreaContext
{
Area[] GetAreas();
}
public class AreaRepository
{
private IAreaContext _areaContext;
protected BaseAreaRepository(IAreaContext areaContext)
{
_areaContext = areaContext;
}
public Area[] GetAll()
{
return _areaContext.GetAreas();
}
}
Then you could define multiple implementations of IAreaContext and injext:
public class MyAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
public class MyOtherAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
Now when you have this setup repository could be easily testable for different behaviors of the context itself. This is just an example to demonstrate idea:
//Arrange
var context = new Mock<IAreaContext>();
context.Setup(m => m.GetAreas()).Verifiable();
var sut = new AreaRepository(context.Object);
//Act
var _ = sut.GetAll();
//Assert
context.Verify();
If you want to test just the base class, then I would create a unit test specific implementation of the class, and just provide any helper functions to test the protected ones. Basically what you have done with MyAreaRepository but as a private class within the test class.

Autofac - Resolve Service on Enum and return different types

I know this is possible using keyed and named services which can be found here in the official documentation.
Keyed and Named Services
In the case of keyed services - If we take a look at the official example we see this.
builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online);
We are binding the common interface IDeviceState to the concrete class OnlineState and OnlineState will resolve out of the container if the enum Device.Online is passed.
var r = container.ResolveKeyed<IDeviceState>(DeviceState.Online);
We are bound by the methods of IDeviceState when r is resolved , but now to my question.
What if my concrete implementations such as OnlineState return unique types , methods on IDeviceState force the same return type on all concrete classes . For Example:
public interface IDeviceState { string GetDeviceStateInformation(); }
Now all my concrete classes are forced to return a string for the GetDeviceState(); method whereas different implementations might return different types.
How do take the same approach but cater for this scenario?
Example Below :
public class OnlineState : IDeviceState
{
public string GetDeviceStateInformation() {
return String.empty;
}
}
public class OfflineState: IDeviceState
{
public string GetDeviceStateInformation() {
//Im forced to use string over due to interface.
//But would actually like to return a int for example
return String.empty;
}
public int GetDeviceStateInformation() {
//This is the actual method i want to call on the implementation class.
//But can not due to IDeviceState
return 5;
}
}
I would like to let autofac handle the resolving of the correct service based upon the enum but not forced to use the methods of the common interface IDeviceState.
var r = container.ResolveKeyed<IDeviceState>(DeviceState.Online);
//I would like result to be different types - right now result will always
//be string but should change depending on the service that is resolved.
var result = r.GetDeviceStateInformation();
My Implementation on Controller:
[Route("api/[controller]/[action]")]
public class DeviceStateController: Controller
{
IIndex<DeviceState, IDeviceState> _states;
public DeviceStateController(IIndex<DeviceState, IDeviceState> states)
{
_states= states;
}
// GET api/values
[HttpGet]
public IActionResult GetDeviceState(DeviceState deviceEnum)
{
//Must Return Different Types
return Ok(_states[deviceEnum].GetDeviceStateInformation());
}
Ok, it seems I got your point. The problem is that C# requires to know all types at compile time. So you are forced to sacrifice the strong typing a little bit somewhere. Take a look on example below. I preserved generic strong typed DeviceState classes, however the result of GetDeviceStateInformation() is passed to controller by object reference. It is not an elegant approach, of cource, C# has its own limitations.
public class DeviceStateController : Controller
{
IIndex<DeviceState, IDeviceState> _states;
public DeviceStateController(IIndex<DeviceState, IDeviceState> states)
{
_states = states;
}
// GET api/values
[HttpGet]
public async Task<IActionResult> GetDeviceState(DeviceState deviceEnum)
{
//Must Return Different Types
var result = await _states[deviceEnum].GetDeviceStateInformation();
return Ok(result);
}
}
[TestFixture]
public class DeviceStateControllerTests
{
[Test]
public async Task GetDeviceStateTest()
{
// Arrange
var builder = new ContainerBuilder();
builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online);
builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState.Offline);
builder.RegisterType<DeviceStateController>();
var container = builder.Build();
var controller = container.Resolve<DeviceStateController>();
// Act
var stringResult = (OkObjectResult)await controller.GetDeviceState(DeviceState.Online);
var intResult = (OkObjectResult)await controller.GetDeviceState(DeviceState.Offline);
//Assert
Assert.AreEqual(stringResult.Value, "Online");
Assert.AreEqual(intResult.Value, 404);
}
}
public interface IDeviceState
{
Task<object> GetDeviceStateInformation();
}
public interface IDeviceState<T> : IDeviceState
{
new Task<T> GetDeviceStateInformation();
}
public abstract class DeviceState<T> : IDeviceState<T>
{
public abstract Task<T> GetDeviceStateInformation();
async Task<object> IDeviceState.GetDeviceStateInformation()
{
return await GetDeviceStateInformation();
}
}
public class OnlineState : DeviceState<string>
{
public override async Task<string> GetDeviceStateInformation()
{
return await Task.FromResult("Online");
}
}
public class OfflineState : DeviceState<int>
{
public override async Task<int> GetDeviceStateInformation()
{
return await Task.FromResult(404);
}
}
public enum DeviceState
{
Online = 1,
Offline = 2
}
Hope it helps.
Segregate the interface, Its one or the SOLID principles eg https://www.dotnetcurry.com/software-gardening/1257/interface-segregation-principle-isp-solid-principle

Mock method return value with read only property

I wish to test a method which queries a third-party library. The library returns an object with a IReadOnlyCollection property.
There is no constructor to set the value of the property and the object has no interface for me to mock.
I have used Moq to mock the interface for the service that I call, but I can't create a mocked return value as I can't set the property.
public interface IHitService {
public Hit GetHit();
}
public class Hit {
public Hit() {
}
public IReadOnlyCollection<string> Result { get; }
}
public class TestingClass {
public void MyTest() {
Hit hit = new Hit() {
// cannot set this property
Result = new List<string>() { "hello","goodbye" };
}
Mock<IHitService> service = new Mock<IHitService>();
service.Setup(c => c.GetHit).Returns(hit);
}
}
What would be the best way for me to generate the return value to test my method? Wrapping the object with a new property to hide the base does not work.
You can use unit-test frameworks that allow you to change the behavior of a concrete object, for example in this case i used Typemock Isolator to try and solve your issue, it allows you to change the the return value of the result property so can "set" for your test without changing your code or adding extra code:
public void TestMethod1()
{
List<string> s = new List<string> { "sfas", "asfsa", "blbba" };
var hit = Isolate.Fake.NextInstance<Hit>();
Isolate.WhenCalled(() => hit.Result).WillReturnCollectionValuesOf(s);
}
In this test i mocked the Hit class and modified the return value of the Result property to a list of strings i created.
If you need to test a third-party library, it would be a better idea to create your own abstraction (interface) and rely on that for both testing and real code:
public interface IHitService
{
IHit GetHit();
}
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
In your application code, you can create a simple wrapper class that implements IHit by delegating to the concrete third-party class. Now you can test the interface by mocking it as needed.
In general, if you can't change 3rd party code, build an adapter to it and use your own abstraction :-
public interface IHit
{
IReadOnlyCollection<string> Result { get; }
}
public interface IHitService
{
IHit GetHit();
}
public class HitAdapter : IHit
{
private Hit _hit;
public HitAdapter(Hit hit)
{
_hit = hit;
}
public IReadOnlyCollection<string> Result => _hit.Result;
}
public class TestingClass
{
public void MyTest()
{
var hitMock = new Mock<IHit>();
hitMock.Setup(c => c.Result).Returns<IReadOnlyCollection<string>>(x => new List<string>() {"hello", "goodbye"});
var service = new Mock<IHitService>();
service.Setup(c => c.GetHit()).Returns<IHit>(x => hitMock.Object);
}
}

Categories