I'm starting to learn MVVM in C# with mvvmlight. From an other project, I have a given (but self-made) REST-API as a dll. This dll I'm trying to use in this new project. It is completly based on this API. I'm unsure about the "model"-part and don't want to repeat myself while coding.
Problem is like this: The application has several "plugins/sections". Let's look at a sample like the "groups" section. Now the API defines a groups-Entity-Class with all properties like "groupname, permissions, members". Then, the Application must have a groups model and also a groupsViewModel and a GroupsView for the UI. There, I also must list/show "groupname, permissions, members".
Question is: Do I have to redeclare all the properties from the dll-entity-class in the mvvm-model-class? Or what is the best way to use a rest api? Is there any pattern. I read about the Extension Object Pattern. But I have no clue.
Hint: Since the API is written by myself (only classes, no mvvm or other frameworks), I could modify it as needed.
Thanks in advance!
Take a look at the Repository Pattern: https://msdn.microsoft.com/en-us/library/ff649690.aspx. Basically you create a repository which does the API calls, and transforms the entities to a format you can use in your view.
If the objects from the API are already sufficient you can simply return them, otherwise convert them in the Repository to something more useful.
In the ViewModel you then simply ask the repository to return the model, and need not to care how and in what format it got them.
Small Example:
interface IApiRepository
{
Task<ObservableCollection<ApiModel>> GetApiModelsAsync();
}
class ApiRepository : IApiRepository
{
private async Task<ObservableCollection> GetApiModelsAsync()
{
var myCollection = new ObservableCollection<ApiModel>();
var result = await DoMyApiCall();
foreach (result as item)
{
var newModel = new ApiModel();
newModel.fillFromApi(item);
myCollection.Add(newModel);
}
return myCollection;
}
}
class MyViewModel : ViewModelBase
{
private readonly IApiRepository _apiRepository;
public MyViewModel(IApiRepository apiRepository)
{
_apiRepository = apiRepository;
InitializeViewModel();
}
private ObservableCollection<ApiModel> _apiModels;
public ObservableCollection<ApiModel> ApiModels
{
get { return _apiModels; }
set { Set(ref _apiModels, value); }
}
private async void InitializeViewModel()
{
//as soon as the repo is finished ApiModels will raise the RaisePropertyChanged event
ApiModels = await _apiRepository.GetApiModelsAsync();
}
}
//in you ViewModelLocator
SimpleIoC.Default.Register<IApiRepository, ApiRepository>();
SimpleIoC.Default.Register<MyViewModel>();
//construct your viewmodel (with the injected repository)
var vm = SimpleIoc.Default.GetInstance<MyViewModel>();
with the help of this pattern you can do some other awesome things:
if you add a new data source you need only to change the repository and not the ViewModel.
if you want to test your view (for example in Design Mode) you can inject a MockApiRepository which returns sample data instead of doing an API call
Related
I have a simple requirement I am trying to achieve. Basically I have a view that gets populates with a list of businesses. The property for the list of businesses is embodied in my viewmodel class which in turn is bound to the view. This is a simple MVC application with a list of business.
However, the issue I have is that I derive the list of business for another class which is a dependency to the view model, and its basically similar to a repository which I call BusinessService. Busy service is comprised of async methods and this is the dilemma I have, when the call is made from the Ctor of the viewModel or the getter of the property, my application hangs. The call is to a EF database asynchrounous too within the businessservice and am not sure what is the correct approach for this. Please see code below:
ViewModel:
#region Ctor
public BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
InitBusinesses().Wait(); //OPTION 1
}
#endregion
#region Properties
public IEnumerable<BusinessViewModel> _businesses;
public IEnumerable<BusinessViewModel> Businesses
{
get
{
if (_businesses == null)
{
InitBusinesses().Wait(); //OPTION 2
}
return _businesses;
}
set => _businesses = value;
}
private async Task InitBusinesses()
{
var response = await _businessService.Get();
Businesses = response.IsSuccessful
? response.Data.Select(p => new BusinessViewModel(_builder, p))
: new List<BusinessViewModel>();
}
BUSINESS SERVICE:
#region Service Methods
public async Task<Response<IEnumerable<Models.Business>>> Get()
{
var data = await Db.Businesses.ToListAsync();
return new Response<IEnumerable<Models.Business>>
{
IsSuccessful = true,
Message = "Successful",
Data = Mapper.Map<List<Models.Business>>(data)
};
}
Please may you advise the best pattern and the correct way to do this, I already know this is wrong> Thank you
I wrote an article on the subject.
When the UI framework asks your code to display something, it must be displayed immediately (synchronously). ViewModel constructors and data-bound properties should be synchronous and immediate. Doing network I/O is simply not an option; even if you got it working (which is possible), all that would do is block your UI thread, degrading your user experience.
A more proper solution is to synchronously initialize into a loading state ("Loading..." message, spinner, whatever) and also start the asynchronous operation. Then, when the operation completes, update the UI with the actual data.
You should consider using a factory method that returns a Task
private BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
}
public static async Task<BusinessListViewModel> Create(IBusinessService businessService, IStringBuilder builder)
{
var instance = new BusinessListViewModel(businessService, builder)
await InitBusiness();
return instance;
}
I'm new to unit testing and I'm really stuck atm so I could really use some help.
Some application info
I have a WPF application in MVVM. It gets data from a database (classes generated via .edmx).
All linq queries are handled by methods in the Database class.
In CustomerListViewModel, it makes a list of all Customers to be shown in the CustomerListView.
My problem
I am new to Unit Testing. I've read about it and tried to make it work. But as I understand, it should/can be done without touching the DB. I tried to find as much info as I could, but it wouldn't work with what I have. And now I'm basically stuck.
My question
How do I unit test this piece of code? How can I know if I've successfully queried the database (with or without touching the DB in the unit test)?
(If I understand it for this piece, I can figure the rest of the classes and methods out on my own)
The code
CustomerListViewModel:
public CustomerListViewModel()
{
MyObservableCollection<Customer> listCustomers = new MyObservableCollection<Customer>();
ListCustomers = App.Database.GetCustomerList();
}
private void GetListCustomers()
{
ListCustomers = App.Database.GetCustomerList();
if (App.Database.hasError)
App.Messenger.NotifyColleagues("SetStatus", App.Database.errorMessage);
}
Database:
public MyObservableCollection<Customer> GetCustomerList()
{
hasError = false;
MyObservableCollection<Customer> customerList = new MyObservableCollection<Customer>();
try
{
QRM_Entities dc = new QRM_Entities();
var query =
from customers in dc.Customer
select customers;
foreach (Customer cust in query)
{
customerList.Add(cust);
}
}
catch (Exception ex)
{
errorMessage = "GetCustomerList() error, " + ex.Message;
hasError = true;
}
return customerList;
}
The way that you have the ViewModel currently setup will make it almost impossible to unit test.
The issue is on this line:
ListCustomers = App.Database.GetCustomerList();
I presume that App is a static and Database is the class that you are using as your Data Access Layer. So everytime that you call the constructor of your CustomerListViewModel you will call the actual Static implementation of App which you would have to setup before creating the View Model, meaning that you would always be testing with the actual Database, which is obviously what you are attempting to bypass.
In comes my favorite software principle the Dependency Inversion Principle, the premise of this is that decouple modules so that your high level module depends on an abstraction of a lower level module. And that details should depend on that abstraction. Effectively you should develop to an interface and provide this interface to dependents.
Taking your example I would extract interfaces for your database interaction and provide these to your View Model, but I'll go a step further and provide this to a model which will be provided to your view model.
IDatabase:
public interface IDatabase
{
IEnumerable<ICustomer> GetCustomerList();
}
ICustomerListModel:
public interface ICustomerListModel
{
ObservableCollection<ICustomer> Customers
{
get;
}
}
CustomerListModel
public class CustomerListModel : ICustomerListModel
{
private readonly IDatabase database;
private readonly ObservableCollection<ICustomer> customers;
public CustomerListModel(IDatabase database)
{
this.database = database;
this.customers = new ObservableCollection(database.GetCustomerList());
}
public ObservableCollection<ICustomer> Customers
{
get
{
return this.customers;
}
}
}
CustomerListViewModel
public class CustomerListViewModel
{
private readonly ICustomerListModel customerListModel;
public CusomterListViewModel(ICustomerListModel customerListModel)
{
this.customerListModel = customerListModel;
}
public ObservableCollection<ICustomer> Customers
{
get
{
return this.customerListModel.Customers;
}
}
}
So what you can see here is that I have extracted an interface for the database which I request the information from, this means that I don't care about the implementation of the IDatabase, I just now that it provides me with a collection of ICustomer's when I call GetCustomerList().
So I inject a copy of the IDatabase into the CusomterListModel class which I can then query knowing that I'll get what I want back correctly. I then inject the ICustomerListModel into the ICustomerListViewModel so that the collection can be presented to the View.
So to test the CustomerListModel I would have a test like:
[Fact]
public void Customers_IsCorrectlyInitialisedAtStartup_Test()
{
var databaseMock = new Mock<IDatabse>();
var customer = new Customer();
var customers = new [] { customer };
databaseMock.Setup(mock => mock.GetCustomerList())
.Returns(customers);
var sut = new CustomerListModel(databaseMock.Object);
Assert.Equal(customers, sut.Customers);
}
In this I have mocked a version of the IDatabase, now you can see how I don't care in the version of CustomerListModel what IDatabase I have as long as I can call GetCustomerList(). This has a setup to return a ICustomer when a call to GetCustomerList() is called. Finally I am asserting that the Customers collection was correctly populated with the returns of the IDatabase call.
Unit testing is a fine art, difficult to understand at first but when you get it working at first you'll pick it up quickly. Some things you may wish to look at to help you with generating unit testable code and actually testing:
Solid Principles, principles that every Software Engineer should at least be familiar with, will help generating code that is testable.
Dependency Injection, the wiki-page on Dependency Injection outlining the pros and cons to injecting the dependency into a constructor, when and how to use it in further examples.
Moq, a friendly and easy to use mocking framework for C#, which I used as part of my example above.
-------Please see updates below as I now have this set up for dependency injection and the use of the MOQ mocking framework. I'd still like to split up my repository so it doesn't directly depend on pulling the windowsUser within the same function.
I have a Web API in an intranet site that populates a dropdown. The query behind the dropdown takes the windows username as a parameter to return the list.
I realize I don't have all of this set up correctly because I'm not able to unit test it. I need to know how this "should" be set up to allow unit testing and then what the unit tests should look like.
Additional info: this is an ASP.NET MVC 5 application.
INTERFACE
public interface ITestRepository
{
HttpResponseMessage DropDownList();
}
REPOSITORY
public class ExampleRepository : IExampleRepository
{
//Accessing the data through Entity Framework
private MyDatabaseEntities db = new MyDatabaseEntities();
public HttpResponseMessage DropDownList()
{
//Get the current windows user
string windowsUser = HttpContext.Current.User.Identity.Name;
//Pass the parameter to a procedure running a select query
var sourceQuery = (from p in db.spDropDownList(windowsUser)
select p).ToList();
string result = JsonConvert.SerializeObject(sourceQuery);
var response = new HttpResponseMessage();
response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");
return response;
}
}
CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
public ExampleController()
{
_exampleRepository = new ExampleRepository();
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 1
I have updated my Controller based on BartoszKP's suggestion to show dependency injection.
UPDATED CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
//Dependency Injection
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 2
I have decided to use MOQ as a mocking framework for unit testing. I'm able to test something simple, like the following. This would test a simple method that doesn't take any parameters and doesn't include the windowsUser part.
[TestMethod]
public void ExampleOfAnotherTest()
{
//Arrange
var mockRepository = new Mock<IExampleRepository>();
mockRepository
.Setup(x => x.DropDownList())
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
ExampleController controller = new ExampleController(mockRepository.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
//Act
var response = controller.DropDownList();
//Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
I need help testing the DropDownList method (one that does include code to get the windowsUser). I need advice on how to break this method apart. I know both parts shouldn't been in the same method. I don't know how to arrange splitting out the windowsUser variable. I realize this really should be brought in as a parameter, but I can't figure out how.
You usually do not unit-test repositories (integration tests verify if they really persist the data in the database correctly) - see for example this article on MSDN:
Typically, it is difficult to unit test the repositories themselves, so it is often better to write integration tests for them.
So, let's focus on testing only the controller.
Change the controller to take IExampleRepository in its constructor as a parameter:
private IExampleRepository _exampleRepository;
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
Then, in your unit tests, use one of mocking frameworks (such as RhinoMock for example) to create a stub for the sole purpose of testing the controller.
[TestFixture]
public class ExampleTestFixture
{
private IExampleRepository CreateRepositoryStub(fake data)
{
var exampleRepositoryStub = ...; // create the stub with a mocking framework
// make the stub return given fake data
return exampleRepositoryStub;
}
[Test]
public void GivenX_WhenDropDownListIsRequested_ReturnsY()
{
// Arrange
var exampleRepositoryStub = CreateRepositoryStub(X);
var exampleController = new ExampleController(exampleRepositoryStub);
// Act
var result = exampleController.DropDownList();
// Assert
Assert.That(result, Is.Equal(Y));
}
}
This is just a quick&dirty example - CreateRepositoryStub method should be of course extracted to some test utility class. Perhaps it should return a fluent interface to make the test's Arrange section more readable on what is given. Something more like:
// Arrange
var exampleController
= GivenAController()
.WithFakeData(X);
(with better names that reflect your business logic of course).
In case of ASP.NET MVC, the framework needs to know how to construct the controller. Fortunately, ASP.NET supports the Dependency Injection paradigm and a parameterless constructor is not required when using MVC unity.
Also, note the comment by Richard Szalay:
You shouldn't use HttpContext.Current in WebApi - you can use base.User which comes from HttpRequestBase.User and is mockable. If you really want to continue using HttpContext.Current, take a look at Mock HttpContext.Current in Test Init Method
One trick that I find very useful when trying to make old code testable when said code is accessing some global static or other messy stuff that I can't easily just parameterize is to wrap access to the resource in a virtual method call. Then you can subclass your system under test and use that in the unit test instead.
Example, using a hard dependency in the System.Random class
public class Untestable
{
public int CalculateSomethingRandom()
{
return new Random().Next() + new Random().Next();
}
}
Now we replace var rng = new Random();
public class Untestable
{
public int CalculateSomethingRandom()
{
return GetRandomNumber() + GetRandomNumber();
}
protected virtual int GetRandomNumber()
{
return new Random().Next();
}
}
Now we can create a testable version of the class:
public class Testable : Untestable
{
protected override int GetRandomNumber()
{
// You can return whatever you want for your test here,
// it depends on what type of behaviour you are faking.
// You can easily inject values here via a constructor or
// some public field in the subclass. You can also add
// counters for times method was called, save the args etc.
return 4;
}
}
The drawback with this method is that you can't use (most) isolation frameworks to implement protected methods (easily), and for good reason, since protected methods are sort of internal and shouldn't be all that important to your unit tests. It's still a really handy way of getting things covered with tests so you can refactor them, instead of having to spend 10 hours without tests, trying to do major architectual changes to your code before you get to "safety".
Just another tool to keep in mind, I find it comes in handy from time to time!
EDIT: More concretely, in your case you might want to create a protected virtual string GetLoggedInUserName(). This will technically speaking keep the actual call to HttpContext.Current.User.Identity.Name untested, but you will have isolated it to the simplest smallest possible method, so you can test that the code is calling the correct method the right amount of times with the correct args, and then you simply have to know that HttpContext.Current.User.Identity.Name contains what you want. This can later be refactored into some sort of user manager or logged in user provider, you'll see what suits best as you go along.
Greetins,
Lets suppose I have a class called Formater:IFormater, and a method LoadData(), like this:
public interface IFormater { void LoadData(string strSomeData); }
public class Formater : IFormater { public void LoadData(string strSomeData) {/*do some magic*/} }
Suppose also I have a class called View:IView and a method LoadRawData(), like this:
public interface IView { void LoadRawData(string strSomeData); }
public class View : IView {
private IFormater _formater;
public View(IFormater formater) { _formater = formater; }
public void LoadRawData(string strSomeData) { _formater.LoadData(strSomeData); }
}
Now, in my prog I create an object of the View class and call LoadRawData(), something like this:
static void Main(string[] args) {
kernel = new StandardKernel(new Modules()); //ninject
formater = kernel.Get<IFormater>(); //ninject
IView view = new View(formater);
view.LoadRawData(args[0]);
}
I use ninject as DI mechanism and actually everything works fine now.
The questions:
Is it a correct to have the IView interface to call Formater::LoadDtata() internally? (For myself I don't see any other way).
Should I have Different names for Formater::LoadData() and View::LoadRawData(), or they should have the same name, or maybe there is a practice how to name them?
I'm sorry. It looks like I made several serius inaccuracies. I have corrected them above.
Actually I don't use MVC pattern. I only thought so.
The point is that I want to isolate display logic from parsing and formating it.
My console app should open a file, read text contents and pass it to formater class, that will do some formating and bring it back (but before that formater will pass it to parser to extract necessary contents from a raw text), like this
view <-> formater <-> parser
This is simple prog and I use it to better understand some best methodologies and practicies like TDD, unit testing and DI.
I'm sorry for previous inconsistiencis.
To answer question 1), as you are using the MVC pattern, your concrete view (not IView which is an interface) should not call IController::LoadData(). The relationship between the Model, View, Controller looks like:
(Image taken from this article which gives a basic definition of MVC)
Instead the controller should place the LoadData data into a model, and then the controller should return a view which is associated with (i.e. can access) this model.
e.g in ASP.NET MVC you could do something like:
public class YourController : Controller
{
IDataRepository db;
public YourController(IDataRepository db)
{
this.db = db;
}
public ViewResult Index()
{
YourModel model = db.LoadData();
return View(model);
}
}
What is not helping you is the fact that you are trying to use the MVC pattern from a console application. I'd suggest working through an MVC tutorial (e.g. this is pretty good) to get a better understanding.
We have an old Silverlight UserControl + WCF component in our framework and we would like to increase the reusability of this feature. The component should work with basic functionality by default, but we would like to extend it based on the current project (without modifying the original, so more of this control can appear in the full system with different functionality).
So we made a plan, where everything looks great, except one thing. Here is a short summary:
Silverlight UserControl can be extended and manipulated via ContentPresenter at the UI and ViewModel inheritance, events and messaging in the client logic.
Back-end business logic can be manipulated with module loading.
This gonna be okay I think. For example you can disable/remove fields from the UI with overriden ViewModel properties, and at the back-end you can avoid some action with custom modules.
The interesting part is when you add new fields via the ContentPresenter. Ok, you add new properties to the inherited ViewModel, then you can bind to them. You have the additional data. When you save base data, you know it's succeeded, then you can start saving your additional data (additional data can be anything, in a different table at back-end for example). Fine, we extended our UserControl and the back-end logic and the original userControl still doesn't know anything about our extension.
But we lost transaction. For example we can save base data, but additional data saving throws an exception, we have the updated base data but nothing in the additional table. We really doesn't want this possibility, so I came up with this idea:
One WCF call should wait for the other at the back-end, and if both arrived, we can begin cross thread communication between them, and of course, we can handle the base and the additional data in the same transaction, and the base component still doesn't know anything about the other (it just provide a feature to do something with it, but it doesn't know who gonna do it).
I made a very simplified proof of concept solution, this is the output:
1 send begins
Press return to send the second piece
2 send begins
2 send completed, returned: 1
1 send completed, returned: 2
Service
namespace MyService
{
[ServiceContract]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1
{
protected bool _sameArrived;
protected Piece _same;
[OperationContract]
public Piece SendPiece(Piece piece)
{
_sameArrived = false;
Mediator.Instance.WaitFor(piece, sameArrived);
while (!_sameArrived)
{
Thread.Sleep(100);
}
return _same;
}
protected void sameArrived(Piece piece)
{
_same = piece;
_sameArrived = true;
}
}
}
Piece (entity)
namespace MyService
{
[DataContract]
public class Piece
{
[DataMember]
public long ID { get; set; }
[DataMember]
public string SameIdentifier { get; set; }
}
}
Mediator
namespace MyService
{
public sealed class Mediator
{
private static Mediator _instance;
private static object syncRoot = new Object();
private List<Tuple<Piece, Action<Piece>>> _waitsFor;
private Mediator()
{
_waitsFor = new List<Tuple<Piece, Action<Piece>>>();
}
public static Mediator Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
_instance = new Mediator();
}
}
return _instance;
}
}
public void WaitFor(Piece piece, Action<Piece> callback)
{
lock (_waitsFor)
{
var waiter = _waitsFor.Where(i => i.Item1.SameIdentifier == piece.SameIdentifier).FirstOrDefault();
if (waiter != null)
{
_waitsFor.Remove(waiter);
waiter.Item2(piece);
callback(waiter.Item1);
}
else
{
_waitsFor.Add(new Tuple<Piece, Action<Piece>>(piece, callback));
}
}
}
}
}
And the client side code
namespace MyClient
{
class Program
{
static void Main(string[] args)
{
Client c1 = new Client(new Piece()
{
ID = 1,
SameIdentifier = "customIdentifier"
});
Client c2 = new Client(new Piece()
{
ID = 2,
SameIdentifier = "customIdentifier"
});
c1.SendPiece();
Console.WriteLine("Press return to send the second piece");
Console.ReadLine();
c2.SendPiece();
Console.ReadLine();
}
}
class Client
{
protected Piece _piece;
protected Service1Client _service;
public Client(Piece piece)
{
_piece = piece;
_service = new Service1Client();
}
public void SendPiece()
{
Console.WriteLine("{0} send begins", _piece.ID);
_service.BeginSendPiece(_piece, new AsyncCallback(sendPieceCallback), null);
}
protected void sendPieceCallback(IAsyncResult result)
{
Piece returnedPiece = _service.EndSendPiece(result);
Console.WriteLine("{0} send completed, returned: {1}", _piece.ID, returnedPiece.ID);
}
}
}
So is it a good idea to wait for another WCF call (which may or may not be invoked, so in a real example it would be more complex), and process them together with cross threading communication? Or not and I should look for another solution?
Thanks in advance,
negra
If you want to extend your application without changing any existing code, you can use MEF that is Microsoft Extensibility Framework.
For using MEF with silverlight see: http://development-guides.silverbaylabs.org/Video/Silverlight-MEF
I would not wait for 2 WCF calls from Silverlight, for the following reasons:
You are making your code more complex and less maintainable
You are storing business knowledge, that two services should be called together, in the client
I would call a single service that aggreagated the two services.
It doesn't feel like a great idea to me, to be honest. I think it would be neater if you could package up both "partial" requests in a single "full" request, and wait for that. Unfortunately I don't know the best way of doing that within WCF. It's possible that there's a generalized mechanism for this, but I don't know about it. Basically you'd need some loosely typed service layer where you could represent a generalized request and a generalized response, routing the requests appropriately in the server. You could then represent a collection of requests and responses easily.
That's the approach I'd look at, personally - but I don't know how neatly it will turn out in WCF.