I have a class in which I have to repeat multiple steps to complete a process like below, this is just a pseudo code to demonstrate what I am asking. Basically each method needs another method to do something, so a few methods are executed one after another to get the desired result, but somehow I don't like this, is there another way to achieve this may be using a design pattern? I have seen the chain of responsibility but that does not suit me as I don't have different type of processors.
Thanks
class Processor
{
void Process()
{
var credentials = GetCredentialsFromDb();
var result = ProcessData(credentials);
}
string GetCredentialsFromDb()
{
return "user";
}
string ProcessData(string credentials)
{
return ExtractData();
}
string ExtractData()
{
return ParseData();
}
string ParseData()
{
return ValidateData(data);
}
string ValidateData(string data)
{
return "validatedData";
}
}
As each of your method calls wraps around the subsequent one, I'd say that the decorator pattern could fit your needs.
This would allow you to specify how the stack is build by only accepting certain types to be wrapped in others, if this is important.
You probably want a Builder Pattern - http://en.wikipedia.org/wiki/Builder_pattern
Basically the builder initializes your object and contains all of the logic, each in separate methods taking arguments for what information they need, for "building up" the end result.
Then you would implement a director that always calls them in sequence.
public static void main() {
var builder = new ProcessorBuilder();
ProcessorDirector director = new ProcessorDirector();
director.Build();
Console.WriteLine(builder.Processor);
}
class ProcessorDirector { //I tell processor builders how to build processors!
ProcessorBuilder _builder {get;private set;}
public ProcessorDirector(ProcessorBuilder builder) {
_builder = builder;
}
public void Build() {
var credentials = _builder.GetCredentialsFromDB();
var data = _builder.ProcessData(credentials);
var isDataValid = _builder.ValidateData();
if(isDataValid) {
_builder.ParseData();
}
}
}
class ProcessorBuilder
{
public string Processor {get;set;}
void ProcessorBuilder()
{
//if you change your end result object into a non-value type, you'd initialize it here.
}
public string GetCredentialsFromDb()
{
return "user";
}
string ProcessData(string credentials)
{
//process
//builder should be stateless, so return data
}
public string ParseData()
{
//parse
}
public string ValidateData()
{
//validate
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am trying to build an app that helps you make dinner decisions. I want the user to be able to click a button and the app should display one random dinner name using an API. I am trying to display the data from an API. This is my code so far. I am getting a null exception. Any assistance is appreciated :)
namespace jello
{
public partial class NetworkingManager : ContentPage
{
private string name;
public string url;
public String Name {
get { return name; }
set
{
name = value;
}
}
public class RecipeClass
{
public class Data
{
public string strMeal { get; set; }
}
public Data data { get; set; }
}
public const string Url = "https://www.themealdb.com/api/json/v1/1/search.php?f=a";
public HttpClient client = new HttpClient();
public NetworkingManager()
{
InitializeComponent();
BindingContext = this;
name = GetDetails();
}
string temp;
public async void GetString()
{
var content = await client.GetStringAsync(Url);
temp = content;
}
public RecipeClass getObj()
{
var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
return output;
}
public String GetDetails()
{
var name = getObj().data.strMeal;
return name;
}
}
}
Your underlying problem is that you want to call something asynchronous from your constructor and constructors cannot be async. You can solve that by using this asynchronous factory pattern:
First make your constructor private so it cannot be called from the outside:
private NetworkingManager()
{
InitializeComponent();
BindingContext = this;
}
Then you make an async method to initialize it:
private async Task<MyClass> InitializeAsync()
{
var temp = await GetStringAsync();
var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
name = output.data.strMeal;
return this;
}
public async Task<string> GetStringAsync()
{
return await client.GetStringAsync(Url);
}
And finally an async method to create it:
public static Task<NetworkingManager> CreateAsync()
{
var manager = new NetworkingManager();
return manager.InitializeAsync();
}
You construct the instance from the outside by doing:
NetworkingManager instance = await NetworkingManager.CreateAsync();
And finally a note about naming: Don't call a class member temp. There's nothing temporary about it. It lives as long as the instance. Don't call a method the very general GetString if it gets a specific string like here. Call it GetMealString or GetMealName or something. The same goes for getObj, which should start with a capital letter by the way. Name your mebers in a clear and specific way and the program's structure will become much clearer to you.
You can do this :
public async void GetMeal()
{
var content = await client.GetStringAsync(Url);
var output = JsonConvert.DeserializeObject<RecipeClass>(content);
Name = output.data.strMeal;
}
And call it like this :GetMeal() you don't need to put name = GetMeal(); Your property
Name is set at the end.
I want to ask the best way how to mock static a method in an another class. I know that mock is not working for a static class. Here is my Code so far. I don't want to call SearchSomething() at the time because it's external interaction
public ResponseBase GetData(string searchId)
{
try
{
var request = new SearchRequest
{
SearchId = searchId
};
var response = SearchLogic.SearchSomething(request);
return response;
}
catch (Exception e)
{
return ResponseBase.ExceptionHandling(e);
}
}
public class SearchLogic(){
public static ResponseBase SearchSomething(SearchRequest request)
{
//Do Something
return new ResponseBase;
}
}
This is my UnitClass
[TestClass]
public class UnitClass
{
[TestMethod]
public void PositiveSearchTest()
{
//arrange
string searchId = "name";
var expected = new SearchRequest();
SearchtController search = new SearchtController();
var staticMock = new Mock<SearchLogic>();
staticMock.Setup(s => s.SearchSomething()).Returns(new ResponseBase());
//act
var actual = search.GetData(searchId);
//assert
Assert.AreEqual(actual, expected);
}
}
While this question gives one way to solve this, my preferred solution would be different: modify SearchLogic so it is no longer static. After that, you can then mock it to your heart's content. Static methods are always a complete pain for unit testing; I try to use them only for situations where there is one and only one correct behaviour.
This obviously assumes you have the ability to modify SearchLogic. If you don't, see the linked question.
I am trying to develop some tests for a Windows 10 UWP application which uses Windows.Devices.Bluetooth.BluetoothLEDevice. I have a plain class that is part of my application which has a private BluetoothLEDevice type field.
class MyDevice
{
private Windows.Devices.Bluetooth.BluetoothLEDevice BluetoothLEDevice;
public string SomeProperty { get; set; }
public MyDevice(Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice)
{
BluetoothLEDevice = bluetoothLEDevice;
var characteristic = BluetoothLEDevice.GetGattService(...)
.GetCharacteristics(...)
.First();
characteristic.ValueChanged += OnValueChanged;
}
// TODO: Write tests for this method
private OnValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
string message = Encoding.ASCII.GetString(args.CharacteristicValue.ToArray());
// Parse `message`
SomeProperty = parsed;
}
...
}
The methods of said class use the events and methods of bluetoothLEDevice, some are private and others are public. How can I test the public methods of MyDevice?
I have tried something like this which I think could work, but I can see that it will take hundreds of lines of code and quite a few extra classes because I would need to implement a lot of stuff in FakeBluetoothLEDevice in orde for it to work properly.
I changed MyDevice to accept a wrapper instead and then create two implementations of the wrapper. One for testing, and the other for real use.
class MyDevice
{
private MyApp.IBluetoothLEDeviceWrapper bluetoothLEDevice;
}
Then in my test I use the fake.
private void ValueChangedEventDataParsingTest()
{
var device = new FakeBluetoothLEDevice();
var myDevice = new MyDevice(device);
device.InvokeValueChanged("this is the value for a fake ValueChangedEvent");
Assert.Equals(probe.SomeProperty, "expected");
}
Are there any frameworks (available for UWP) that would help me achieve what I want? Or even a better approach that would save me some pain?
In stead of focusing on implementation concerns focus on what functionality you want your abstraction to expose. Using your simplified example I was able to replicate it with some refactors to only interact with the desired functionality.
[TestClass]
public class DeviceTests {
[TestMethod]
public void _ValueChangedEventDataParsingTest() {
//Arrange
var message = "message";
var expected = "expected";
var device = new FakeBluetoothLEDevice(message, expected);
var sut = new MyDevice(device);
//Act
device.InvokeValueChanged(message);
//Assert
Assert.AreEqual(expected, sut.SomeProperty);
}
public interface IBlueToothService {
Action<string> ValueChangedHandler { get; set; }
}
public class FakeBluetoothLEDevice : IBlueToothService {
private string message;
private string parsed;
public FakeBluetoothLEDevice(string message, string expected) {
this.message = message;
this.parsed = expected;
}
public Action<string> ValueChangedHandler { get; set; }
public void InvokeValueChanged(string p) {
var handler = ValueChangedHandler ?? delegate { };
if (p == message) {
ValueChangedHandler(parsed);
}
}
}
public class MyDevice {
private IBlueToothService device;
public string SomeProperty { get; set; }
public MyDevice(IBlueToothService device) {
this.device = device;
device.ValueChangedHandler = handler;
}
private void handler(string parsedValue) {
SomeProperty = parsedValue;
}
}
}
Use separation of concerns and move the heavy lifting of implementation concerns behind the actual implementations. It vastly simplifies the consumers of such functionality.
If the concern is to test he parsing functionality then abstract the out into its own concern as well. Don't have classes doing more than they need to (SRP)
private OnValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) {
string message = Encoding.ASCII.GetString(args.CharacteristicValue.ToArray());
// Parse `message`
var parsed = parsingServce.Parse(message);
SomeProperty = parsed;
}
That way the parsing service implementation will only need to be tested for ts core functionality.
But from an abstraction perspective the parser is not needed as a dependency when testing higher level functionality.
I advise reviewing the current design and refactoring it to be more SOLID.
I am trying to serialize my model each second and push it to a server. I have set up a periodic task which executes each second. I call SendNewMessage to execute the push.
The first method call to SendNewMessage() which is called from the constructor runs fine with no exceptions or issues.
When the async task tries to call the SendNewMessage I get an exception and my application shuts down. It is the NewtonSoft code:
String PushModelToServer = JsonConvert.SerializeObject(this, jss); Which fails
Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in
'C:\Users\snovva\Source\Workspaces\HMI\HMI.ViSoft\bin\x86\Debug\HMI.ViSoft.vshost.exe'.
Additional information: The runtime has encountered a fatal error. The address of the error was at 0x71041771, on thread 0x2788. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
public class Model : ModelBase
{
public Model ()
{
PeriodicTask.Run(() =>
{
SendNewMessage();
},
TimeSpan.FromSeconds(1));
SendNewMessage();
}
public void SendNewMessage()
{
// Send the message
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.Formatting = Newtonsoft.Json.Formatting.Indented;
String PushModelToServer = JsonConvert.SerializeObject(this, jss);
sendMessage(System.Text.Encoding.Unicode.GetBytes(PushModelToServer));
}
}
public class PeriodicTask
{
public static async Task Run(Action action, TimeSpan period, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(period, cancellationToken);
if (!cancellationToken.IsCancellationRequested)
action();
}
}
public static Task Run(Action action, TimeSpan period)
{
return Run(action, period, CancellationToken.None);
}
}
More Info As requested:
The call on line 10 in the constructor runs. The serialization works the first time. Since the data in the model is changing I am pushing this model every second to update server. It is the async call which fails. As time passes the data in the model will change.
You can use [IgnoreDataMember] to avoid serializing properties that should not be included.
The code below works in my application, and should hopefully help you arrive at a solution for your app.
I am hoping that the code you show above is a snippet of your real code because there are some potential issues with the 1 second timer, re-entrancy, etc. Instead of doing this timer in the Model constructor, consider moving it to another function/class and setting up the timer/calls from an additional call you setup later...again, just some suggestions on arriving at a good pattern. Do more research here...
Here is how I get my data, what you want in your PushModelToServer:
public class BackupData
{
public List<Vehicles> Vehicles { get; private set; }
public List<FuelStops> FuelStops { get; private set; }
public BackupData(List<Vehicles> vehicles, List<FuelStops> fuelStops)
{
Vehicles = vehicles;
FuelStops = fuelStops;
}
public string ToJson(Formatting formatting = Formatting.None)
{
var json = JsonConvert.SerializeObject(this, formatting);
return json;
}
public static BackupData FromJson(string jsonBackupData)
{
var data = JsonConvert.DeserializeObject<BackupData>(jsonBackupData);
return data;
}
}
Here is a snippet of one of my classes:
[DebuggerDisplay("{VehicleName}")]
public class Vehicles : IComparable<Vehicles>, INotifyPropertyChanged
{
private string id;
public string Id
{
get { return id; }
set
{
if (id != value) { id = value; NotifyPropertyChanged(); }
}
}
private string vehicleName;
public string VehicleName
{
get { return vehicleName; }
set
{
if (vehicleName != value) { vehicleName = value; NotifyPropertyChanged(); }
}
}
public override string ToString()
{
return VehicleName;
}
[IgnoreDataMember]
public UpdateState UpdateState { get; set; }
....
And here is how I get the data so I can use it anywhere I want:
#if WINDOWS_PHONE_APP
private void OnExecuteBackup(SettingsPage obj)
{
#else
private async Task<bool> OnExecuteBackup(SettingsPage obj)
{
#endif
var backupData = App.JournalModel.GetBackupData().ToJson(Formatting.Indented);
...
await SaveBackupFile(file, backupData);
...
public class JournalModel
{
...
public BackupData GetBackupData()
{
var data = new BackupData(Vehicles.ToList(), FuelStops.ToList());
return data;
}
...
Good luck with your project.
Well there must be something the the class You're trying to serialize, that makes the serializer go crazy. Maybe instead of serializing 'this' You should try serializing an actual 'DataObject' - something that can be serialized, and doesn't contain references to Timers, tasks, ect.. ?
There is a set of classes that I do not own - I cannot change them.
I'd like to add an identifying parameter to each, using an existing field in each class that has one.
So, I created a set of extension methods to fetch this field from each class, with a default for any class that does not have a specific implementation.
This works just fine when accessing the new extension method directly (the first three writes in the example below), but when the instances are first passed into a generic method, then the extension method selected is always the one for object (the second three writes).
Am I doing something wrong, or is this a limitation of the C# compiler?
public class Call { public string Number { get; set; } }
public class Message { public string Address { get; set; } }
public class Unknown { }
public static class Extensions
{
public static string ID(this object item) { return "Unknown"; }
public static string ID(this Call item) { return item.Number; }
public static string ID(this Message item) { return item.Address; }
}
internal class Program
{
private static void Main()
{
var call = new Call { Number = "555-1212" };
var msg = new Message { Address = "you#email.com" };
var other = new Unknown();
// These work just as I would expect
// - printing out Number, Address, or the default
System.Console.WriteLine("Call = {0}", call.ID());
System.Console.WriteLine("Message = {0}", msg.ID());
System.Console.WriteLine("Unknown = {0}", other.ID());
System.Console.WriteLine();
// These all print out "Unknown"
System.Console.WriteLine("Call = {0}", GetID(call));
System.Console.WriteLine("Message = {0}", GetID(msg));
System.Console.WriteLine("Unknown = {0}", GetID(other));
}
public static string GetID<T>(T item)
{
return item.ID();
}
}
Overload resolution is performed at compile-time. The compiler knows nothing about T, so the only applicable overload is this one:
public static string ID(this object item) { return "Unknown"; }
If you want to effectively perform overload resolution at execution time, and if you're using C# 4, you might want to consider using dynamic - which unfortunately doesn't support extension methods directly:
public static string GetID(dynamic item)
{
return Extensions.ID(item);
}