How do I chain SourceList observation using ReactiveUI and DynamicData? - ios

Apologies if the terminology is off; I'm an iOS developer having to use Xamarin.iOS to develop an app. I'm using ReactiveUI with DynamicData and an MVVM architecture. I'm fairly happy with RxSwift, and FRP concepts in general. I have a Model that publishes a SourceList<MyThing>, according to the docs, like so:
// Property declarations
private readonly SourceList<MyThing> Things;
public IObservableCollection<MyThing> ThingsBindable { get; }
// Later, in the constructor...
Things = new SourceList<MyThing>();
// Is this of the right type?
ThingsBindable = new ObservableCollectionExtended<MyThing>();
Things
.Connect()
.Bind(ThingsBindable)
.Subscribe();
I can successfully use .BindTo() in my View (i.e. ViewController in iOS-land) to get a UITableView to update when the Model changes:
Model
.WhenAnyValue(model => model.ThingsBindable)
.BindTo<MyThing, MyThingTableViewCell>(
tableView,
new NSString("ThingCellIdentifier"),
46, // Cell height
cell => cell.Initialize());
I'd like, instead of binding directly to the Model, to have the ViewModel subscribe-and-publish (or otherwise proxy) the SourceList<MyThing>, or the bindable version of this, so that the View is only using the ViewModel properties. The SourceList is declared private in the docs; I'm unsure of best practice here: do I make it public and do my Connect() in the ViewModel? Or is there a way of passing on the publicly exposed IObservableCollection<MyThing> ThingsBindable from the ViewModel? I'm also not convinced that ObservableCollectionExtended<MyThing> is the right type for the Bindable property, but it seems to work.
I've tried various combinations of .ToProperty(), .Bind(), .Publish() etc. and making a version of the View-binding Observable in the ViewModel to no avail and am now just throwing autocomplete at the wall to see what sticks. Any direction appreciated. TIA.

I think it was beginners misunderstanding. Here's what I've got working the way I want; maybe it will help other Xamarin.iOS/ReactiveUI/DynamicData newbies.
In my model I declare both a private SourceList and a publicly exposed IObservableList<MyThing>:
private readonly SourceList<MyThing> _ModelThings;
public IObservableList<MyThing> ModelThings;
Then instantiate them in my constructor:
_ModelThings = new SourceList<MyThing>();
ModelThings = _Things.AsObservableList();
In my ViewModel I declare a local ObservableCollectionExtended<MyThing> and bind that to the Model's public property:
public ObservableCollectionExtended<MyThing> ViewModelThings;
// Then, in the constructor:
ViewModelThings = new ObservableCollectionExtended<MyThing>();
model.ModelThings
.Connect()
.Bind(ViewModelThings)
.Subscribe();
In my ViewController I bind the table to the ViewModel.ViewModelThings, as in the question. If I wanted to have another level of Model I could simply pass through the Model.ModelThings and .Connect().Bind() lower down, as Glenn hinted in his comment.
FWIW, I found Roland's Blog (specifically the sections on Observable Lists/Caches) to be more straightforward to understand than the GitHub docs.

Related

MVC - How to instantiate, store and make a typed variable available throughout the application, once per page view

I am developing an MVC app to serve multiple domains - each is a branch of a larger company.
A LocalBranch class stores details such as phone, address, email, location coordinates etc.
I want to create a single instance of this class per http request and have it available throughout the application - from within controllers, views, some helper classes and other code.
Is there a recommended way of doing this?
Right now I have it as a property on a BaseController and use ViewBagto pass it to views. But I would prefer it strongly typed in Views if possible.
I don't want to put it in an application variable, because we need to serve different values to different domains.
I would rather avoid a session variable if possible because we might scale up to use multiple servers in the future, and I've heard this doesn't play well with sessions.
Please feel free to update tags / title if you think there is a clearer way of expressing what I'm after. Thank you.
The best way to maintain your state in a web application per request is simply use the HttpContext class.
You need to store your state(LocalBranch) as an Item in the HttpContext:
HttpContext.Current.Items.Add("LocalBranch", GetLocalBranch());
You can fetch the Item all across your application like this:
LocalBranch branch = HttpContext.Current.Items["LocalBranch"] as LocalBranch;
The Items property is simply a key value Dictionary. The value is an object. You will have to check for nulls and this is really similar to the Session object you know. The main difference is the scope. The HttpContext is a dot net object that has a lifetime of an http request.
Now using the HttpContext the way I've shown you is the simplest way to do it.
You can go two steps forward and use a framework called Unity and add a lifetime to your objects.
Unity does much more and the lifetime management is just one gem.
You can create a custom HttpContext lifetime that generates objects per request. Something like this.
And them all you need to do is:
1.Register you LocalBranch class with the HttpContext lifetime.
2.Add a static Current property which will use the Unity container and resolve the correct instance of LocalBranch.
3.Use it something like this: LocalBranch.Current
BTW, you can use Unity's dependency injection for injecting objects into controllers and other modules. That's a better practice then just using the static Current property.
You kind of have two questions here. The first is "How do I create a single instance of this class per HttpRequest?" The second is "How do I make this available to strongly typed views?"
The first has pretty much been answered by #amir-popovich to use dependency injection. However, FWIW I would probably use Ninject instead of Unity (just preference, really) and I would probably implement it differently. I would not use HttpContext, and simply build a service (which is instanciated using Ninject's OnePerHttpRequest Module, passing the domain as an argument to get the proper values).
Then, in order to add these LocalBranch values to your strongly typed View Model, you can first create a base view model which holds this type:
public class BaseViewModel
{
public LocalBranch Branch {get;set;}
}
Then, make all of your current view models inherit this base type
public MyViewModel : BaseViewModel
{
public string SomeValue {get;set;}
}
Then in your controller, it is easy enough to add these values from the service you created from the first step
public ActionResult SomeAction()
{
var vm = new MyViewModel();
vm.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
//do other stuff
return View(vm);
}
However, that gets pretty tedious to add that to each controller action, so you can instead create a Result Filter to add it for you:
public class LocalBranchResultFilter : FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
//This method gets invoked before the ActionResult is executed.
filterContext.Controller.ViewData.Model.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
}
}
Now, you can just decorate your Controller and/or Actions with the filter (you could even set it in the Global Filters if you want).
You can embed the child actions into your layout or a view. You can even cache its output so you don't keep re-querying the database.
controller
[ChildActionOnly]
[OutputCache(Duration=500, VaryByParam="*")]
public ActionResult Info()
{
var localBranch = db.GetLocalBranch();
return PartialView("_Info", localBranch);
}
_Info view
This bit will get inserted into your other views
#model LocalBranch
<span>#Model.address</span>
<span>#Model.phone</span>
Use in _Layout or other view
<p>lorem ipsum...</p>
#Html.Action("Info")

What's the simplest way to intercept a method call for added functionality?

Suppose i have a repository that returns a list of Posts. The repository interface has a GetAll() method which does what it suggests.
Now in keeping with the theory that i shouldn't be putting domain logic in the repository, i want to intercept calls to the concrete GetAll() method such that i can add the following logic to the GetAll() result:
return GetAll().OrderByDescending(p => p.Posted).ToList();
The reason i want to intercept this is because (1) i don't want to have the client remember to call an extension method (OrderByDescending or some useless wrapper of that), i want it called every time and (2) i don't want to have all my concrete implementations have to remember to order the GetAll() result - i want this logic in a single place external to any repository.
What's the easiest way to do this?
I'm already using StructureMap so if i can intercept with this it might be a low cost option. But i don't think SM intercepts method calls, just the creation of the object instance?
Do i need to go to a proxy or mixin pattern? Do i need to go all-in with Castle Dynamic Proxy? Or is there another method i should consider or perhaps a combination?
I'm really interested in a concrete suggestion to my particular example above. I'm novice to AOP so please be gentle.
Went with the DynamicProxy option. It was easier to use than i thought.
All it took was the using Castle.DynamicProxy; reference...
A bit of IInterceptor...
public class PostRepoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name.Equals("GetAll", StringComparison.InvariantCultureIgnoreCase))
invocation.ReturnValue = this.GetModifiedGetAllResult(invocation.ReturnValue);
}
private object GetModifiedGetAllResult(object getAllResult)
{
return Post.GetOrderedPosts((IList<Post>)getAllResult);
}
}
Two new lines in StructureMap config:
public RepoRegistry()
{
var pg = new ProxyGenerator();
For<IPostRepository>()
.EnrichAllWith(z => pg.CreateInterfaceProxyWithTarget<IPostRepository>(z, new PostRepoInterceptor()));
}
..and it's done. GetAll() now behaves how i want. I can still use the interfaces the way i'm familar and i've kept it all DRY and decoupled for DDD.
Thanks to Sam and Andre.
AFAIK, StructureMap only intercepts object construction, so using it it's not going to work.
I don't know Castle, but I think that the idea - here - is to apply Decorator pattern, so you could also do it by yourself without recurring to a third party library by following the steps described in the previous link.
That's how I'd do it, since I'm not a big fan of AOP.
HTH
No, it can not change the return value. However, you can access the target inside aspect to change target's property. Assuming you has already Repository defined, here is the code to add post processing aspect to change target property.
IRepository<decimal> Rep = new Repository();
IRepository<decimal> tpRep = (IRepository<decimal>)ObjectProxyFactory.CreateProxy(Rep,
new String[] { "GetAll" },
null,
new Decoration((x, y) =>
{
Console.WriteLine("Entering " + x.GetType().ToString());
if (x.GetType().ToString() == "ThirdPartyHR.Repository")
{
List<decimal> decimals = ((Repository)x).RepList;
IEnumerable<decimal> query = decimals.OrderByDescending(num => num, new SpecialComparer()).ToList<decimal>();
((Repository)x).RepList = (List<decimal>)query;
}
}, null));
tpRep.GetAll();
List<decimal> lstRep = Rep.RepList;
If needed, I can send you complete working code. And, if possible, please reply to me from the article "Add Aspects to Object Using Dynamic Decorator" since I don't automatically get the message here.
There is an article Add Aspects to Object Using Dynamic Decorator.
It describes an approach to adding aspects to object at runtime instead of adding aspects to class at design time. Looks like that is what you want.

Dynamic typed ViewPage

Is this possible? Here's what I'm trying:
public ActionResult Index()
{
dynamic p = new { Name = "Test", Phone = "111-2222" };
return View(p);
}
And then my view inherits from System.Web.Mvc.ViewPage<dynamic> and tries to print out Model.Name.
I'm getting an error: '<>f__AnonymousType1.Name' is inaccessible due to its protection level
So basically, is what I'm trying to do just not possible? Why or why not?
Update: here's my view
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ...>
<%=Model.Name%>
<%=Model.Phone%>
</asp:Content>
The View constructor is built-in to the framework.
Anonymous types cannot be returned by a method; they are only valid within the scope of the method in which they are defined.
You should use a Model class that you have previously defined and pass that to your View. There is nothing wrong with passing a Model class that does not have every field defined.
Update:
I think I was wrong before. This should work. Perhaps the problem is within the View. Can you post more code? Especially the View and its constructor.
Update the Second:
Ok, I was wrong about passing an anonymous type to another method for use as a dynamic variable -- that can be done.
But I was also wrong in my belief that what you're trying to do would work. Unfortunately for you, it will not. The problem is that you are using ViewPage<TModel>, which uses a ViewDataDictionary<TModel> internally. Because they require strong types, you won't be able to use dynamic objects with them. The internal structure just doesn't use dynamic internally, and specifying dynamic as the type fails.
What would be needed is a DynamicViewPage class and corresponding DynamicViewDataDictionary class that accept object and store it internally as a dynamic. Then you could use an anonymous type and pass it to your Views.
That said, you would not gain anything. You would be able to specify your Views as you have done (i.e. <%=Model.Name%>), but you would not benefit from strong typing. There would be no intellisense and there would be no type safety. You'd do just as well to use the untyped ViewDataDictionary as #Dennis Palmer suggests.
This has been an interesting (and, unfortunately for me, absorbing) thought experiment, but I think, ultimately, that it's not going to happen. Either declare a public type and pass it to your Views, or use the untyped dictionary.
What benefit were you hoping to get from using the dynamic type here?
Using the ViewData dictionary is a very easy way of adding arbitrary objects/items to your view output.
You don't need reflection to get the property names within your View. Just use ViewData.Keys to get the collection of names.
Edit: I've just learned a bit more about dynamics myself and I think maybe you need to create your own dynamic object class that inherits from DynamicObject. You'll want to have a private dictionary in that class and then override TrySetMember and TryGetMember.
Edit Aside: I think one advantage of a strongly typed ViewModel is that you can accept it as a parameter in your POST Action methods. The MVC framework will handle the model binding and in the action method you simply have an instance of your ViewModel class. I don't think you'll have that advantage with a dynamic even if they do work.
Edit Result: Well, I tried using a class derived from DynamicObject, but VS2010 crashes when it tries to render the view. I don't get any exception, just a hard crash and Visual Studio restarts. Here's the code I came up with that causes the crash.
The custom dynamic class:
public class DynViewModel : DynamicObject
{
private Dictionary<string, object> ViewDataBag;
public DynViewModel()
{
this.ViewDataBag = new Dictionary<string, object>();
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.ViewDataBag[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.ViewDataBag[binder.Name];
return true;
}
}
In the controller:
public ActionResult DynamicView()
{
dynamic p = new DynamicViewModel.Models.DynViewModel();
p.Name = "Test";
p.Phone = "111-2222";
return View(p);
}
My view is basically the same as what is listed in the question:
<p>Name: <%=Model.Name %></p>
<p>Phone: <%=Model.Phone %></p>
My Conclusion: This might work, but in the Beta 1 of VS2010 I can't figure out why my code causes Visual Studio to crash. I'll try it again in VS2010 Beta 2 when it is released because it is an interesting exercise in learning about dynamics. However, even if this were to work, I still don't see any advantage over using the ViewData dictionary.
Phil Haack to the rescue! Here's a blog post by Phil Haack that might help you out. It looks like it is what you were looking for. Fun With Method Missing and C# 4
The actual error here (<>f__AnonymousType1.Name' is inaccessible due to its protection level) is the result of using anonymous types. Anonymous types are implicitly internal (at least in C#), therefore they can only be accessed normally from the same assembly. Since your view is compiled into a separate assembly at runtime, it can't access the internal anonymous type.
The solution is to pass concrete/named classes as models to your view. The view itself can still use dynamic if you want.
On .NET 4.0 Anonymous types can easily be converted to ExpandoObjects and thus all the problems is fixed with the overhead of the conversion itself.
Check out here

MVP : other constructor's parameters than view and model?

I'm experimenting with implementing a lightweight mvp framework with Delphi 2009.
Views are passive but supports databinding (via an interface property).
I'm facing a dilemna:
I've several very similar views/presenter/model triad, ie :
order form and a customer form = behavior and logic is the same but the datasource for databinding is different and the form title too. the datasource is a common property for all my models so it's not a problem, to set the form title, I'm forced to hard code it in my presenter InitView method
All is working good, but I'm in a situation where I have several simple mvp triads very similar. I want to refactor it but in that case I will have to pass some parameters to the mvp constructor.
So far I'm doing like that :
Create the view
Create the model
Create the presenter and inject model and view in the constructor
In fact, I'm facing a choice :
Having some very generic views/presenter, use them like that but inject 1 or 2 parameters in the constructor
Having some views/presenters superclass, and derive all my similar view/presenter from them and set some specific values in the overriden methods.
Can you give me some hints / advices ?
(sorry if i'm not very clear)
Fred,
I will choose 1 & 2 in a way that is having an abstract views/presenters that contain generic behaviors and creates abstract functions that could be possible specific behaviors implemented by subclasses.
for example,
public abstract class AbstractPresenter{
// subclass will be implemented
public abstract void InitView(Model model, View view);
}
and then you might have sublcasses, OrderFormPresenter and CustomerFormPresneter extends from AbstractPresenter.
public OrderFormPresenter extends AbstractPresenter{
public void InitView(Model model, View, view){
// do something specific values
}
}
public CustomerFormPresenter extends AbstractPresenter{
public void InitView(Model model, View, view){
// do something specific values
}
}
Please, correct me if it goes wrong direction.
I hope it helps.
Tiger
I'd create a generic view/presenter with parameters and subclass only when needed.
Another approach (and the way that I once solved this problem so it worked very well) is to build a generic "metadata" interface into the model, and the view (either interfaces, or via class inheritance) then use these generic interfaces in your presenter. I chose to use inheritance for my model, and interfaces for my view (was easer to slap a interface on an existing form than to require form/frame inheritance across the board). In my solution, the constructor for the presenter took 3 parameters, the model, the view and the "MVP name". I used the name of the MVP to load settings which were specific to the current scenario.

In TDD and DDD, how do you handle read-only properties in fakes?

Question
How do you handle read-only fields when creating fakes?
Background
I'm in the beginner stages of using ASP.Net MVC and am using Steven Sanderson's Sports Store and Scott Gu's Nerd Dinner as examples. One small problem that I've just hit is how to work with read-only properties when doing fakes. I'm using LINQToSQL.
My interface is:
public interface IPersonRespository
{
Person GetPerson(int id);
}
and my fake becomes
public class FakePersonRepository
{
public Person GetPerson(int id)
{
return new Person {id="EMP12345", name="John Doe", age=47, ssn=123-45-6789, totalDrWhoEpisodesWatched=42};
}
}
Here's my problem. The fields id, ssn and totalDrWhoEpisodesWatched are read-only, so the above code won't actually work. However, I don't recognize how to create a fake new person and set a read-only property. I'm sure there is a solution, but I haven't come across it yet in my searches.
Update: Inheritance + Property Hiding as a Potential Solution?
I haven't yet decided upon a firm solution to the problem. I dislike the notion of modifying my Domain classes for the purposes of creating fakes. To me, adding markup to the domain classes in order to do testing is a form of added coupling -- coupling to the implementation of your test. I'm now investigating another possibility, which is to create a FakePerson class, which inherits from Person, but hides the properties with new read-write properties.
public class FakePerson: Person
{
public new int age { get; set; }
public new string ssn { get; set; }
public new int totalDrWhoEpisodesWatched { get; set; }
}
So far, this solution is how I am leaning. It does break the Liskov Substitution Principle, however that doesn't bug me as much in a test project. I'd be glad to hear any criticism and/or feedback on this as a solution.
Winner: Mock Frameworks
Moq appears to do the job. My last solution of hiding the property through inheritance does, in fact, work, however by using Moq, I get a standardized set of functionality that is more maintainable. I assume that other mock frameworks have this functionality, but I haven't checked. Moq is said to be more straightforward for the beginning mock writing, which I definitely am right now.
Consider mocking the Person type in your test. Example using Moq:
var mock = new Mock<Person>();
mock.SetupGet(p => p.id).Returns("EMP12345");
mock.SetupGet(p => p.ssn).Returns("123-45-6789");
mock.SetupGet(p => p.totalDrWhoEpisodesWatched).Returns(42);
return mock.Object;
Otherwise, try finding out how LINQ to SQL sets those read only properties.
EDIT: If you attempt the above and Moq throws an ArgumentException in the SetupGet call with the message "Invalid setup on a non-overridable member: p => p.id", then you need to mark the property as virtual. This will need to be done for each property whose getter you wish to override.
In LINQ to SQL, this can be done in the OR designer by selecting the property, then in the Properties window set Inheritance Modifier to virtual.
You can only set readonly properties in the constructor of the class. The Person object should have a constructor that accepts id, ssn, and totalDrWhoEpisodesWatched. Of course, if this is a linqtosql generated object, you might have issues modifying that as the code is auto-generated.
You could consider using a mapped object to expose in your repository ... so you'd never actually have to use your linqtosql object as your model.
In .NET, you could mark your setters as "internal" and use the InternalsVisibleTo assembly attribute to make internals visible to your test assembly. That way your setters won't be public, but you can still access them.
note: even though the question isn't tagged .NET, I assumed it was based on your usage of object initializer syntax. If my assumption was wrong, this suggestion does not apply (unless the language you're using has an equivalent feature, of course).
If it's for tests - consider using reflection. That wouldn't involve messing around your domain model.
For example - i got FactoryBase class, which uses reflection to set needed prop by lambda expression through parameters (like this). Works like a charm - creating new factory is simple as defining repository type and default entity data.
I also use Moq. I love it and it works great. But, before I started using Moq, I wrote many fakes. Here's how I would have solved the problem using fakes.
Since a fake can have additional methods that the "production" implementation doesn't have, I would add a few extra methods to my fake implementation to handle setting the read-only portion.
Like this:
public class FakePersonRepository : IPersonRespository
{
private IDictionary<int, Person> _people = new Dictionary<int, Person>();
public Person GetPerson(int id) // Interface Implementation
{
return _people(id);
}
public void SetPerson(int id, Person person) // Not part of interface
{
_people.Add(id, person);
}
}

Resources