monocross 初探

monocross是基于C#的跨平台开发技术,下面以官方的一个demo讲一下大概的开发流程

这个demo是以纽约时报的一个API来获取一个最佳销售商的名单。

Project Structure

MonoCross  solution consists of the  MonoCross  framework ( MonoCross .Navigation), a shared application (BestSellers), and one or more container projects (Console.Container, Touch.Container).
其中Container就是针对各个平台的容器 比如iOS、android、webKit、wp等。而共享的部分就包括,Model和Controller,这两个部分的文件是给各个平台共享的,所以只需要写一份Model和一份Controller然后不同的Container根据自己的需要进行组织界面。
下面是monocross改进之后的MVC架构

这种适合于monocross的MVC架构,在controller和view中间定义了接口,这样就可以通过接口去和各个平台的view进行通信,然后呢controller就负责navigation、data access、初始化model等,而view只负责渲染界面。
下面是官方原文
So the MonoCross implementation of MVC uses a separated view interface that allows the shared application code to take care of navigation, data access, and initialization of the model, while the platform-specific views handle the rendering.

In summary your  MonoCross  deployable application consists of your shared application code, bound to a single platform container. Deployment to multiple platforms is as simple as adding additional containers.

Designing your Model

Model就是存储数据的结构,数据处理不需要Model,而是controller来执行的。
Design your model in a way that delivers only the information your audience needs at the time they need it. Less is definitely more when it comes to mobile application design.
设计Model的时候,不要用要把所有数据和数据库或者API对应,全都拿下来,只要拿用户需要的,关心的数据就可以了。

Building your Shared Application

下面是整个monocross中我觉得最重要的一个部分,也就是controller部分的构建

Implementing your Controllers

 You'll need at least one controller for each model type that you wish to display in your views. In BestSellers our first view is of the category list:
public class CategoryListController : MXController<CategoryList>
{
...
}
在monocross中,所有的conreollers都会继承于抽象类MXController<T>,这个类定义了在monocross application中最基本的你所需要实现的方法。
也是在controller中初始化要传给container的Model数据,在MXController.load()方法中进行初始化
public class CategoryListController : MXController<CategoryList>
{
public override string Load(Dictionary<string, string> parameters)
{
Model = new CategoryList();
string urlCategories = "http://api.nytimes.com/svc/books/v2/lists/names.xml?api-key=37623584ce54f502598f220836e1c052:12:62921147";
try
{
XDocument loaded = XDocument.Load(urlCategories);
var categories = from item in loaded.Descendants("result")
select new
{
name = (string)item.Element("list_name"),
};
foreach (var category in categories)
{
Model.Add(category.name);
}
}
catch
{
Model.Add("No List retrieved");
}
return ViewPerspective.Default;
}
}
在load()方法中,调用了相应的API,然后初始化了controller的Model属性(在这个例子中,就是CategoryList对象)。其他Controller的构建方法类似。

Initializing your Application

在定义好Model和controllers之后,就需要在shared application中注册controllers.这时候要用到MSApplication
The MXApplication class is an abstract super-type that contains the constructs needed to define your workflow, and register your controllers for use in your container. So we will define our BestSellers app as follows:
namespace BestSellers
{
public class App : MXApplication
{
...
}
}
初始化shared application需要重写OnAppLoad()方法,这个方法会在应用初始化的时候被调用,包含那些建立你的应用结构的所必须的代码
public class App : MXApplication
{
public override void OnAppLoad()
{
// Set the application title
Title = "Best Sellers";
// Add navigation mappings
NavigationMap.Add("", new CategoryListController());
NavigationMap.Add("{Category}", new BookListController());
NavigationMap.Add("{Category}/{Book}", new BookController());
// Set default navigation URI
NavigateOnLoad = "";
}
}

Registering your Controllers

这一段用原文比较清晰。
The most important part of your app initialization is the registration of your controllers. The  NavigationMap  property is a collection of all the controllers necessary to render your application to your desired platform target(s).
The NavigationMap is keyed using a URI template model which defines your application workflow. Each user-action will initiate a navigation based on the URI patterns defined in your NavigationMap, so design it carefully. Be sure to include any parameters, (defined using squiggly-bracket syntax), that are needed to properly initialize your model. These parameters will be processed by the MXApplication.Navigate()method and passed to your MXController<T>.Load() method.

In our BestSellers example, the navigation map will contain three controllers:
NavigationMap.Add("", new CategoryListController());
NavigationMap.Add("{Category}", new BookListController());
NavigationMap.Add("{Category}/{Book}", new BookController());
When the user selects a category, the category value will be passed as the navigation URI and will load the BookListController  from the  NavigationMap . The application will then pass the category value to the controller on the parameters argument of the  Load()  method where it can be used to initialize the  BookList object for that category from the Best Sellers API.
Subsequently when the user selects a book, the category and book values will be passed, loading theBookController, and the book information retrieved in a similar manner.
这种navigation的范例是monocross pattern的关键,在创建应用过程中提供了巨大的灵活性,但是也需要考虑仔细各个conreoller之间的关系以及所需参数。
 Controller-View combinations can be re-used at different points in your workflow by simply defining multiple endpoints in your NavigationMap with unique URI definitions.

Building your Platform Container

在完成了shared application之后,剩下的就只是在特定的平台去展示这些数据了。
下面的例子用一个控制台来自作为容器,因为不牵涉任何移动平台,所以最能体现monocross 的 container pattern。

Constructing your Views

When constructing your views, MonoCross lets you take full advantage of the capabilities of your native platform. So construct your views in a manner that will present your information in a manner optimized for your deployment.
MonoCross views必须实现IMXView接口,也可以是实现继承与IMXView接口的其他接口。
On platforms where your view class must already inherit another base class an alternative strategy is for your view class to hold a local object that implements IMXView and delegate all IMXView calls to this local object (composition rather than inheritance).
上面这段不好翻译,直接看之后理解就好了。
For our BestSellers CategoryList model the view is defined as follows:
public class CategoryListView : MXView<CategoryList>
{
...
}
注意,view的Render()方法必须被重写,  implement any actions necessary to initialize and present your model information to the target platform.
 If you have used composition to implement IMXView it will be necessary to handle Render() using an event or override an alternative method on your local IMXView implementer because you obviously can not override Render() itself.
In the case of our Console platform, we will iterate the Model and construct a simple menu of options from which the user can select:
public class CategoryListView : MXView<CategoryList>
{
public override void Render()
{
System.Console.WriteLine("Categories");
System.Console.WriteLine();
foreach (string category in Model)
{
System.Console.WriteLine(Program.navigationKeys.Count + ".  " + category);
Program.navigationKeys.Add(Program.navigationKeys.Count, category);
}
}
}

Buiding your App to the Container

Now that your views are defined, all that remains is to initialize your application and bind it to your container. there are three steps to the process that must be completed in the Main() method, or equivalent entry point to your platform-specific container application
  • App Initialization – set the view load event delegate, and initialize the MXContainer with an instance of your app.
  • View Registration – register your views with your container using the MXContainer.AddView()method.
  • Initial Navigation – perform an MXContainer.Navigate() navigation to the initial view of your application
下面按照这三个步骤进行初始化程序并且将shared application绑定到指定container中
The  MXContainer.OnViewLoadComplete  event fires as a part of every navigation when the shared application has completed the Model load. This event will trigger the passing of control from the shared application to your platform specific deployment. Simply set the delegate to the method you would like called to process your view rendering:
MXConsoleContainer.OnLoadComplete += (IMXController controller) => { MXConsoleContainer.Instance.ControllerLoadComplete(controller); };
To bind your application, simply call the  MXContainer.Initialize()  method passing a new instance of your app. For our Best Sellers sample we add the following code:
MXConsoleContainer.Initialize(new BestSellers.App());
To provide the shared application access to your views you must register them by populating the MXApplication.Instance.Views  collection. For Best Sellers we've created three views, so each of them needs to be added here:
// initialize views
MXConsoleContainer.AddView(new Views.CategoryListView(), ViewPerspective.Default);
MXConsoleContainer.AddView(new Views.BookListView(), ViewPerspective.Default);
MXConsoleContainer.AddView(new Views.BookView(), ViewPerspective.Default);
Finally, we need to perform a navigation to the default view in our shared application. The MXApplication.Instance.NavigateOnLoad  property provides an easy way to accomplish this. For Best Sellers, (and most other applications), that means a call to this endpoint to load your initial view:
MXConsoleContainer.Navigate(MXApplication.Instance.NavigateOnLoad);
Here's the full code for the Best Sellers sample initialization:
static void Main(string[] args)
{
// initialize container
MXConsoleContainer.Initialize(new BestSellers.App());
// initialize views
MXConsoleContainer.AddView(new Views.CategoryListView(), ViewPerspective.Default);
MXConsoleContainer.AddView(new Views.BookListView(), ViewPerspective.Default);
MXConsoleContainer.AddView(new Views.BookView(), ViewPerspective.Default);
// navigate to first view
MXConsoleContainer.Navigate(MXApplication.Instance.NavigateOnLoad);
}

OK,这样就完成了 就可以运行了。因为这个主要是为了让我们知道monocross的一个项目开发的流程和结构,所以中间省略很多细节,这些我会在后面的关于monocross的文章中再介绍。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值