I have two function which have some common functionality (i.e. to make connection with service and close connection after calling). I made a method named "InvokeService" with parameter of Func in it.How can I get parameters of request in InvokeService? I mean I need to get the object value of request? You can clear be clear by my demo code given below:
public void Method1(){
InvokeService(()=> _service.getMathod1(request);
}
public void Method2(){
InvokeService(()=> _service.getMathod2(request);
}
public void InvokeService(Func<T> request){
//service open
//I need here a complete object of the request of Method2 and its parameters
request.Invoke();
//service close
}
If any thing ambiguous or not understandable feel free to ask me.
You may want to use the template method pattern:
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
In your case, you can have something like this:
public abstract class AbstractClass
{
protected abstract void PrimitiveOperation();
public void TemplateMethod()
{
// before common functionality
PrimitiveOperation();
// after common functionality
}
}
class ConcreteClassA : AbstractClass
{
protected override void PrimitiveOperation()
{
// your A logic
}
}
class ConcreteClassB : AbstractClass
{
protected override void PrimitiveOperation()
{
// your B logic
}
}
If you want to return something different for each concrete class or have a different parameter depending the concrete class, you can achieve that with generics. Let me know if that is the case.
It can be solve by using Reflection;
request.GetMethodInfo()
Related
I need to unify few classes that have same purposes but and use same method but with different parameters and results.
It probably sound odd to you so let me explain.
I have multiple classes that are connecting to multiple rest/web services to grab data from them. For this example lets say that all of those rest are weather forecast services. Each do same thing. Return forecast for some area, but all of them are doing it on theirs own way. For each service I have class that implement gathering data from it and map to my object :
public class AForecast
{
public AForecastResult GetForecast (AForecastRequest request)
{
// Grab Forecast
}
}
public class BForecast
{
public BForecastResult GetForecast (BForecastRequest request)
{
// Grab Forecast
}
}
I'm calling those classes, grab forecast data and then map it into my own object that I work with and this is fine. My problem is that right now I have 13 forecast services. Many of them are using similar method to map forecast result into my own object. Next problem is also that right now probably only I know how can I add new forecast into system. I want to unify that to be able add some interface into Forecast service implementation, and also some base forecast mapper.
I created Interface, but since i Have no idea how forecast result and request will look like it is very generic :
public interface IForecast<out TResult, in TRequest>
{
TResult GetForecast(TReqiest request)
}
For each forecast I created separate interface that will implement IForecast
public interface IAForecast : IForecast<AForecastResult, AForecastRequest>
{
}
And my AForecast implementation started look like this :
public class AForecast : IAForecast
{
public AForecastResult GetForecast (AForecastRequest request)
{
// Grab Forecast
}
}
Thanks to that I have Forecast services that have it own interface that have common base interface.
Problem is when I want to use it in base class which will be able to call each forecast service and map objects :
public abstract ForecastBase
{
private readonly ?ForecastService _service;
protected ForecastBase(?ForecastService service)
{
_service = service;
}
public MapedObject GetForecast(DateTime date, string zip)
{
var request = GetRequest(date,zip);
var forecastServiceResponse = _service.GetForecast(request);
return Map(forecastServiceResponse);
}
protected abstract MapedObject Map(?Response response);
protected abstract ?Request GetRequest(DateTime date, string zip);
}
Oh this was long. Now final question how can I implement ForeCast base class ? Base on my architecture how can I know what type will be ?ForecastService, ?Request and ?Response. I wish i can make mapper like that :
public class AMap : ForecastBase
And know that in that case ?ForecastService will be IAForecast, ?Request will beAForecastRequest and ?Response will be AForecastResponse ?
In case you need more explanation feel free to ask.
I think what you need is the keyword where (not only but it's going to play a very important role here).
I defined the interfaces for the request and response like this:
public interface IForecastRequest
{
}
public interface IForecastResult
{
}
Then we can go on to defining the interface for the Forecast itself:
public interface IForecast<out TForecastResult, in TForecastRequest>
where TForecastResult : IForecastResult where TForecastRequest : IForecastRequest
{
TForecastResult GetForecast(TForecastRequest request);
}
What happens here is the following. Additionally to your solution, we restrain the generic types to implement our interfaces for request and response. We can then add the generic method to get the ForecastResult. By the way GetForecast also doesn't seem like a great name. Better would be GetResult or GetForecastResult otherwise you'd expect a different return-type.
Now we can implement the BaseForecast. I hope I understood correctly what this is supposed to do. Because you called it ForecastBase, I wasn't sure if this was supposed to do the same thing as IForecast. Maybe a better name would be a good idea here. I implemented it like this:
public abstract class BaseForecast<TForecastResult, TForecastRequest>
where TForecastResult : IForecastResult where TForecastRequest : IForecastRequest
{
private readonly IForecast<TForecastResult, TForecastRequest> _service;
protected BaseForecast(IForecast<TForecastResult, TForecastRequest> service)
{
_service = service;
}
public MappedObject GetForecast(DateTime date, string zip)
{
TForecastRequest request = GetRequest(date, zip);
TForecastResult forecastServiceResponse = _service.GetForecast(request);
return Map(forecastServiceResponse);
}
protected abstract MappedObject Map(TForecastResult response);
protected abstract TForecastRequest GetRequest(DateTime date, string zip);
}
Here we also have to add the wheres since we'll have to call the generic methods of the IForecast interface with the same constraints. You can see that in the constructor we provide an instance of an implementation of IForecast which will be our service. This service uses the two generic types we also have in the definiton of this baseclass. The GetForecast-method can now use the generic method of IForecast and the own generic method (GetRequest) to do get the MappedObject (which I don't know what it is). The types all align and you get handy intelisense and compiletime-typechecking for IForecastRequest and IForecastResult.
Please let me know if I understand the purpose of the ForecastBase correctly or not.
I hope this helps. I'm happy to try and answer any questions you might have on this.
Edit:
I wish i can make mapper like that..
The way you show there doesn't use any generic-type parameters. As far as I understand your intent, you will not be able to do this without specifying what result and request you want to use.
My way of creating an implementation for this is the following:
// implement request
public class SomeForecastRequest : IForecastRequest
{
}
// implement result
public class SomeForecastResult : IForecastResult
{
}
// implement forecast itself
public class SomeForecast : IForecast<SomeForecastResult, SomeForecastRequest>
{
public SomeForecastResult GetForecast(SomeForecastRequest request)
{
// return the result you got from wherever
}
}
public class SomeMapper : BaseForecast<SomeForecastResult, SomeForecastRequest>
{
public SomeMapper(IForecast<SomeForecastResult, SomeForecastRequest> service) : base(service)
{
}
protected override SomeForecastRequest GetRequest(DateTime date, string zip)
{
// return a request from wherever
}
protected override MappedObject Map(SomeForecastResult response)
{
// map the response and return it
}
}
Edit 2:
I just read your comment which reads the following:
.. They are not related to each other. And those object don't have own interfaces, and I don't wrapped it in own interface
If you want to keep it this way, there is no way you can create a base-class for you mapper. The mapper need to know that the AForecast has a method called GetForecast. If it doesn't how is it going to call it. You're going to be in compiler-error land if you try this. You need to tell the compiler "this class can handle any class if it has the GetForecast-method" otherwise it will refuse to try and call GetForecast. The way to tell this to the compiler is by saying "dude look I got this awesome interface which has the GetForecast-method. I'm only going to allow the caller to use a class which implements this very interface so you can be sure the GetForecast-method exists. Alright?". This is why you use the where keyword and I thank you for your question because this is a very good (but not too easy) example on how to use it.
Edit 3:
By the way there is nothing stopping you from using classes instead of interfaces for IForecastRequest and IForecastResult (of course you would change the name but everything else could stay the same). I don't know what your request and response object is supposed to do/store so I don't know if using classes over interfaces is the right call for you here.
I just wanted to throw out there that this would be possible too.
I'd love to hear some feedback from you :)
I have an interface:
interface ISqlite
{
void insert();
void update();
void delete();
void select();
}
And custom service class:
class SqliteService
{
public SQLiteDatabase driver;
public SqliteService() {
SqliteConnection(new SQLiteDatabase());
}
public void SqliteConnection(SQLiteDatabase driver)
{
this.driver = driver;
}
public void select(ISqlite select) {
select.select();
}
public void insert(ISqlite insert) {
insert.insert();
}
public void delete(ISqlite delete)
{
delete.delete();
}
}
And last class Pacients that realizes ISqlite interface:
class Pacients: ISqlite
{
public List<ClientJson> pacients;
public Pacients() {
this.pacients = new List<ClientJson>();
}
public void add(ClientJson data) {
this.pacients.Add(data);
}
public void insert()
{
throw new NotImplementedException();
}
/* Others methos from interface */
}
I try to use my code like as:
/* Create instance of service class */
SqliteService serviceSqlite = new SqliteService();
/* Create instance of class */
Pacients pacient = new Pacients();
pacient.add(client);
serviceSqlite.insert(pacient);
As you can see above I send object pacient that realizes interface ISqlite to service. It means that will be called method insert from object pacient.
Problem is that I dont understand how to add data in this method using external class: SQLiteDatabase()? How to get access to this.driver in service class from object pacient?
Edit 1
I think I must move instance of connection new SQLiteDatabase() to db inside Pacients class is not it?
Generally speaking, I would favor a solution where the data objects themselves don't know anything about how they're stored, i.e. they have no knowledge of the class that communicates with the database. Many ORMs do just that.
Of course it might not be easy depending on the specifics of your situation... Try to examine what your methods on each object actually need; generally speaking they need the values of properties, and what column each property corresponds to, right? So any external class can do this if it knows these bits of information. You can specify the name of the column with a custom attribute on each property (and if the attribute isn't there, the column must have the same name as the property).
And again, this is the most basic thing that ORMs (Object Relational Mappers) do, and in addition they also manage more complicated things like relationships between objects/tables. I'm sure there are many ORMs that work with SqlLite. If you're OK with taking the time to learn the specifics of an ORM, that's what I would recommend using - although they're not silver bullets and will never satisfy all possible requirements, they are in my opinion perfect for automating the most common day to day things.
More to the point of the question, you can of course make it work like that if you pass the SQLiteDatabase object to the methods, or keep it in a private field and require it in the constructor or otherwise make sure that it's available when you need it; there's no other simple solution I can think of. And like you pointed out, it implies a certain degree of coupling.
You can change the signature of interface's methods to pass an SQLiteDatabase object.
interface ISqlite
{
void insert(SQLiteDatabase driver);
void update(SQLiteDatabase driver);
void delete(SQLiteDatabase driver);
void select(SQLiteDatabase driver);
}
Example call from the service:
public void insert(ISqlite insert)
{
insert.insert(driver);
}
I think you can figure out the rest by yourself.
once again I'm here for help. I'm writing my first "real-like" application to practice what I learned and I am not sure about my approach. I'll try to explain it as best as my english allows me.
Application consist of base abstract class and three classes inherited from that base.
abstract class BaseClass
{
// Some stuff...
// This method is used in all classes. It gets whole adb output
// and returns it as a string for future formating
protected string ProcessAdbCommand(string command)
{
try
{
_processInfo.Arguments = command;
Process adbProcess = Process.Start(_processInfo);
adbProcess.WaitForExit();
return adbProcess.StandardOutput.ReadToEnd();
}
catch (Exception e)
{
WriteToLog(e.Message);
return null;
}
}
}
After ProcessAdbCommand returns output, I will call another method which handles output as needed. Principle is always the same - format output and make somethinkg usefull based on the output.
Now I'd like to make clear, that method responsible for output handling needs to be in every inherited class. But problem is that in very class it returns different value type (boolean, List of IDevice and strings)
I am struggling here. First I wanted to make it protected abstract. Somethink like
abstract class BaseClass
{
// Some stuff...
// Same as above
protected string ProcessAdbCommand(string command)
{
//Same as above
}
//Method which will be implemented in every inherited class differently
protected bool|List<IDevice>|string ProcessAdbOutput(string adbOutput)
{
//Method implementation
return bool|List<IDevice>|string
}
}
But as I discovered it is not possible to override return type. And because method will be always used only internally in classes, I do not see reason to "force" it using interfaces.
After some time I game up and decided to forget about forcing implementation in derived classes and simply write them as I need. But do you think it is "legal" approach? How would you solve problem like that in "real world" application? Is there something I am still missing or is my approach simply wrong? Thank you.
Struggling Greenhorn.
One possible approach would be to make the abstract base class generic and accept a T parameter, which can also be the output of your ProcessAdbOutput method. Then, you make the method abstract to make sure any derived type has to implement it:
public abstract class BaseClass<T>
{
protected string ProcessAdbCommand(string command)
{
return string.Empty;
}
public abstract T ProcessAdbOutput(string result);
}
public class DerivedClass : BaseClass<IList<IDevice>>
{
public override IList<IDevice> ProcessAdbOutput(string result)
{
return new List<IDevice>();
}
}
I'm currently working on a C# program that creates a List, of object Task, the object Task is a base class and many other inherit from it. What I want to is compare the type of one of the object within said list to see which form should be opened in order to edit it.
This is the code I have already created.
private void itemEdit_Click(object sender, EventArgs e)
{
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
if(checkTask.GetType is Note)
{
noteBuilder editNote = new noteBuilder(todoList);
editNote.Show();
}
else if(checkTask.GetType is extendedTask)
{
extendedTaskBuilder editTask = new extendedTaskBuilder(todoList);
editTask.Show();
}
else if(checkTask.GetType is Reminder)
{
reminderBuilder editReminder = new reminderBuilder(todoList);
editReminder.Show();
}
else if (checkTask.GetType is Appointment)
{
appointmentBuilder editAppointment = new appointmentBuilder(todoList);
editAppointment.Show();
}
}
On a secondary note would it be easier if instead of passing the list between the forms and generating a new object of the form that display information that I instead pass a single object between forms and just update the form every time a new element is added to the list.
Many thanks
Have you tried checking like this:
if (checkTask is Note)
{
}
...
Have you considered creating a base class for all types you are now switching between and call a virtual (abstract) method?
Put all code now in the if in the overridden abstract method.
Advantages:
- The intelligence of the switch is within the classes where it belongs.
- When a new type is added you get a compiler error to also add this feature to the new type.
I suggest that instead of doing that series of ‘if’ clauses, you use inheritance to achieve what ou need. First you create a virtual method in your base class. A virtual method means it won't have any implementation in the base class, only the declaration:
public class Task
{
(...)
public virtual void ShowEditForm(IList todoList);
(...)
}
Then you create the child class methods (I'm assuming the todoList object is a IList, but just change it if it is not).
public class Note: Task
{
(...)
public override void ShowEditForm(IList todoList)
{
(new noteBuilder(taskToEdit)).Show();
}
(...)
}
public class Reminder: Task
{
(...)
public override void ShowEditForm(IList todoList)
{
(new reminderBuilder(taskToEdit)).Show();
}
(...)
}
I didn't write all the classes, but I think you've got the idea. To call the method, you just call the method from Task class, and the right method will be executed:
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
checkTask.ShowEditForm(todoList);
This way, when you want to create new types of Task, you just have to create the child class, with the proper method, and the inheritance system will do the rest.
One more thing, the override keyword in the child method declaration is important, because it says to the compiler that this method should be called even if you call it from the BaseClass.
First, to your second note. What you are talking about doing is having a global object that all forms refer to in some parent. That can work, however you will need to make sure there is some mechanism in place that makes sure all of the forms are synchronized when one changes, and this can get messy and a bit of a mess to maintain. I am not necessarily advocating against it per say, but just adding words of caution when considering it :)
As to your posted code, it would probably be better to turn this into a Strategy Pattern approach, where all forms inherit from a base class/interface which has a Show method. Then all you need to do is call checkTask.Show(todoList);. If you do not want that coming from the Task, then you could have your forms all inherit from the above base and you could use a factory pattern that takes in the Task and list and returns the appropriate form on which you simply call form.Show();
Code like this is difficult to maintain, you are probably better off abstracting this out, like so (assuming Task is not the one included in .net):
public interface IBuilder
{
void Show();
}
public abstract class Task
{
// ...
public abstract IBuilder GetBuilder(TaskList todoList);
// ...
}
public class Note : Task
{
public override IBuilder GetBuilder(TaskList todoList)
{
return new noteBuilder(todoList);
}
// ...
}
// etc.
private void itemEdit_Click(object sender, EventArgs e)
{
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
IBuilder builder = checkTask.GetBuilder(todoList);
builder.Show();
}
Alternately, you can use an injection pattern:
public abstract class Task
{
protected Task(Func<TaskList, IBuilder> builderStrategy)
{
_builderStrategy = builderStrategy;
}
public IBuilder GetBuilder(TaskList todoList))
{
return _builderStrategy(todolist);
}
}
public class Note : Task
{
public Note(Func<TaskList, IBuilder> builderStrategy) : base(builderStrategy) {}
}
// ...
note = new Note(x => return new noteBuilder(x));
I have some classes inherit from existing Windows Controls like TextBox and DateTimePicker, ..etc
I want to add custom functionalities for these classes like (Read, Alert, ...etc)
these added functionalities are the same in all these classes
The problem is: these classes inherited from difference parents so I can't put my added functionalities in the parent class,
What's the best practice in this case:
repeat the code in each inherited
class
Use a separated class have the
functionalities as Static Methods
with parameter from an interface, implement this interface for the classes and
then pass them.
Use a separated class like the second approach but with Dynamic parameter (which added in C# 4.0)
or other !!
Thanks in advance
I'd consider option 4: composition.
First, define your set of functionality. We'll assume that your partial list is exclusive, so "Read" and "Alert."
Second, create a single class that implements this functionality, something like MyCommonControlBehaviors. I'd prefer this implementation not be static if possible, though, it may be generic.
public MyCommonControlBehaviors
{
public Whatever Read() { /* ... */ }
public void Alert() {}
}
Third, use composition to add an instance of this class to each of your custom control types and expose that functionality through your custom control:
public class MyCustomControl
{
private MyCommonControlBehaviors common; // Composition
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
}
Depending on specifics, you can get creative to the degree necessary. E.g., perhaps your custom behaviors need to interact with private control data. In that case, make your control implement a common ICommonBehaviorHost interface that your common behaviors need. Then pass the control into the behavior class on construction as an instance of ICommonBehaviorHost:
public interface ICommonBehaviorHost
{
void Notify();
}
public class MyCommonControlBehaviors
{
ICommonBehaviorHost hst = null;
public MyCommonControlBehaviors(ICommonBehaviorHost host)
{
this.hst = host;
}
public void Alert() { this.hst.Notify(); } // Calls back into the hosting control
// ...
}
public class MyCustomControl : ICommonBehaviorHost
{
private MyCommonControlBehaviors common = null;
public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}
Use Composition instead of Inheritence!
If you must, what I would probably do is create extension methods for each class and then reference the actual coded needed for these in some other object all the extension methods can call.
This way the code isn't duplicated, and the extension methods make it look like the methods should be in the object.
It's the same essentially by creating a static method and doing: Functions.DoSomething(my_Object);
But I always like: my_Object.DoSomething() better in an OO language.
I would suggest defining an interface for the behaviors, and then (to keep from repeating yourself) create extension methods on that interface definition for your shared methods. (Kinda like your second option, only with extension methods instead of totally static methods).