I have a class that receives an ODataQueryOptions object, I'd like to call this class from another one, something like this:
public class DataService() {
public async Task<MyEntity> GetData(ODataQueryOptions options){
//Something here...
}
}
public class OtherClass(){
public async Task<MyEntity> GetDataFromService() {
var service = new DataService();
var response = DataService.GetData(//--What should I send here?--)
}
}
In the example above, my OtherClass.GetDataFromService doesn't have any ODataQueryOptions object, is it possible to create an empty object or with some kind of default state?
Related
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
}
}
}
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");
I'm trying to use DI to bind a different implementation of my networking class. I've been able to do this successfully using a none generic version of the class. My implementation is as follows:
class MainClass
{
public static void Main(string[] args)
{
IKernel kernel;
// Hardcode here but will be managed by build system.
bool runningInProd = false;
if (runningInProd)
{
kernel = new StandardKernel(new RealNetworkModule());
}
else
{
kernel = new StandardKernel(new FakeNetworkModule());
}
Session session = kernel.Get<Session>();
session.Authenticate();
}
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(RealRequestSender));
}
}
public class FakeNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(FakeRequestSender));
}
}
}
Class that uses my IRequestSender:
public class Session
{
IRequestSender requestSender;
[Inject]
public Session(IRequestSender requestSender)
{
this.requestSender = requestSender;
}
public void Authenticate()
{
Console.WriteLine(requestSender.Send("Hello There"));
}
}
The IRequestSender interface:
public interface IRequestSender
{
string Send(string request);
}
And the two different implementations:
public class RealRequestSender: IRequestSender
{
public string Send(string request)
{
return "RealRequestSender right back at you: " + request;
}
}
public class FakeRequestSender: IRequestSender
{
public string Send(string request)
{
return "FakeRequestSender right back at you: " + request;
}
}
This is very straightforward and it works; however, what I need is for my IRequestSender to use Generic types rather than string for input output:
public interface IRequestSender<RequestT, ResponseT> where RequestT: class where ResponseT: class
{
RequestT Send(RequestT request);
}
And the impl's:
public class FakeRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
public class RealRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
I've come across several examples that address this issue and I've tried to base my implementation on them but I have failed. Here are the two problems that I'm running into:
1) Binding: this is the main problem. Here is what my binding looks like based on solutions I have seen online:
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender<>)).To(typeof(RealRequestSender<>));
}
}
VSCode gives me the error:
Program.cs(29,29): Error CS0305: Using the generic type 'IRequestSender<RequestT, ResponseT>' requires 2 type arguments (CS0305) (DI)
Based on this error and what I have read online it is still not clear to me what I need to do here.
2) Accessing IRequestSender: the solution to this might be clear once I know how to fix binding. In the original implementation I used [Inject] to get access to the IRequestSender I need in my Sessions class. However now in the generic version I imagine I will not be able to do this. If I were to use RequestSender without DI it would look like:
RequestSender <AuthRequest, AuthResponse> requestSender = new RequestSender<AuthRequest, AuthResponse>();
or
RequestSender <UserRequest, UserResponse> requestSender = new RequestSender< UserRequest, UserResponse >();
for any number of different types.
So I'm not sure how to go about accessing the RequestSender in this scenario.
Given your current interface, you'll have to specify the generic type arguments when injecting. Assuming your request and response are both strings, your constructor would look like:
public Session(IRequestSender<string, string> requestSender)
{
this.requestSender = requestSender;
}
If you don't want to specify the arguments at creation/injection time, you'll have to change the design a bit. I can't say for certain with the sample code you provided, but it might be possible to remove the generic type args from your interface and place them on the method instead:
public interface IRequestSender
{
RequestT Send<RequestT, ResponseT>(RequestT request)
where RequestT: class
where ResponseT: class;
}
With that definition, you'd inject IRequestSender, and then specify the generic type parameters when calling. For example,
string myResponse = requestSender.Send<string, string>("my string");
I have the following method in public abstract A : IVirtualMachineExporter :
public override void Prepare() { ... }
I call the Prepare from another class B:
public sealed class B
{
public new ExportJobRequest Request { get { return (ExportJobRequest)base.Request; } }
private void ExportTask()
{
IVirtualMachineExporter exporter = CreateExporter();
exporter.Prepare();
}
}
Request containing public bool isAdHoc { get; set; }. I want to use information from this property inside Prepare(). How can I do this? I don't want to change Prepare() signature.
How can I do this without changing Prepare signature?
Well, somehow Prepare needs an instance to call isAdHoc on, so if you don't want to change the method signature, can you change the class or interface?
something like:
IVirtualMachineExporter exporter = CreateExporter(Request);
exporter.Prepare();
or
IVirtualMachineExporter exporter = CreateExporter();
exporter.Request = Request;
exporter.Prepare();
In class A, expose a public property IsAdhoc.
Set the IsAdhoc property on class A, prior to calling Prepare from class B.
So...
Class A
public bool IsAdhoc { get; set; }
// Inside this method, do something based on the IsAdhoc property above.
public override void Prepare() { ... }
Class B
public sealed class B
{
public new ExportJobRequest Request { get { return (ExportJobRequest)base.Request; } }
private void ExportTask()
{
IVirtualMachineExporter exporter = CreateExporter();
exporter.IsAdhoc = this.Request.isAdhoc;
exporter.Prepare();
}
}
Or, you could pass the boolean value to the CreateExporter method, which could set it on the new exporter class via its constructor.
It looks like B depends on an IVirtualMachineExporter, and the implementation of IVirtualMachineExporter (A) depends on a Request.
B shouldn't know anything about A or what it depends on. It should only care about the IVirtualMachineExporter interface and calling Prepare().
You could create it like this:
public abstract class A : IVirtualMachineExporter
{
private readonly ExportJobRequest _request;
public A(ExportJobRequest request)
{
_request = request;
}
public override void Prepare()
{
//Now Prepare() has access to the Request because
//it's contained within A, the class that actually needs it.
}
}
Similarly, pass an interface (not a concrete implementation) to the constructor for B.
public sealed class B
{
private readonly IVirtualMachineExporter _exporter;
public B(IVirtualMachineExporter exporter)
{
_exporter = exporter;
}
private void ExportTask()
{
//Can this isAdhoc property be a property of IVirtualMachineExporter,
//or can the Request be a property? Will every implementation of the
//interface have a request?
//exporter.IsAdhoc = this.Request.isAdhoc;
_exporter.Prepare();
}
}
I don't have the specifics of your design. But if B is going to depend on an interface (IVirtualMachineExplorer) then it shouldn't know or care about any of the inner details of any class that implements the interface.
I want to implement a generic List procedure to various partial C# classes. I will use this generic method to fill comboboxes for filtering data.
So far i have try this:
Interface
First I create a generic interface and a custom class
public class Enumerador
{
public int ID{ get; set; }
public string Description{ get; set; }
}
interface IEnumerador
{
IEnumerable<Enumerador> Enumerar();
}
Then on every class i want this behavior I implement this interface like this:
public IEnumerable<Enumerador> Enumerar()
{
using (var context = new OhmioEntities())
{
Clientes _allClients = new Clientes();
_allClients.RazonFantasia = "Any Client";
_allClients.ID_Cliente = -1;
var query = context.Clientes;
var _clients = query.Where(f => f.Activo == true).OrderBy(o => RazonFantasia).ToList();
_clients.Insert(0, _allClients);
var p = from cli in _clients
select new Enumerador { ID = cli.ID_Cliente, Description = cli.RazonFantasia };
return p.ToList();
}
}
Now i get a generic list filled and returned. Now my problem is that i need to send this to client over WCF, and i want a generic (polymorphic?) method to do that.
So far i resolve it like this:
Method A
public IEnumerable<Enumerador> GetClients()
{
Clientes _cli = new Clientes();
return _cli.Enumerar();
}
Method B
public IEnumerable<Enumerador> GetVendors()
{
Vendors _vnd = new Vendors();
return _vnd.Enumerar();
}
So my questions are
*Is there a polymorphic generic way to write Method A and Method B on a single procedure (Because they respond with same generic type)?
*Will this be compatible with WCF service? Thanks for everything!
UPDATE
Ok. I half way done. Now it almos work. I've modified my method like this:
public IEnumerable<Enumerador> GetEnumerador<T>() where T : IEnumerador, new()
{
T _obj = new T();
return _obj.Enumerar();
}
If i call it from within the class work great. But if a call it from WCF Cliente i get:
The non generic Method
'Ohmio.Client.OhmioService.OhmioServiceClient.GetEnumerador()' cannot
be used with types arguments
Any Idea?
UPDATE 2
This is my service contract:
public interface IOhmioService
{
[OperationContract]
IEnumerable<Enumerador> GetEnumerador<T>() where T : IEnumerador, new();
}
This is my class implementation:
public class OhmioService : IOhmioService
{
public IEnumerable<Enumerador> GetEnumerador<T>() where T : IEnumerador, new()
{
T _obj = new T();
return _obj.Enumerar();
}
}
And call it from client like this:
public IEnumerable<Enumerador> Clients { get; set; }
Clients = this.serviceClient.GetEnumerador<Clientes>();
You could try something like this:
public IEnumerable<Enumerador> GetClients<T>() where T : IEnumerador, new()
{
T _cli = new T();
return _cli.Enumerar();
}
It forces T to be IEnumerador and have a parameterless constructor.
Call it like this:
IEnumerable<Enumerador> c = GetClients<Clientes>();
And
IEnumerable<Enumerador> v = GetClients<Vendors>();