Rockford Lhotka

 Thursday, September 5, 2019

After 15+ years of self-hosting my blog with dasBlog I've decided to shift over to using GitHub and Jekyll for a more modern experience - primarily for you as a reader. I think the new site offers a much better reading experience.

As an author I've been using MarkdownMonster to write and publish my content for the last 18-24 months. I imagine I'll continue with that approach, but now the content will flow through GitHub instead of direct-posting to dasBlog.

This does mean a new blog URL: https://blog.lhotka.net

The old http://lhotka.net/weblog will remain in place as an archive, at least for now. I suppose I'll eventually take it down, but I'm not in a hurry.

So friends, farewell to this old blog location. I'll see you over at the new Rockford Lhotka blog.

Android | CSLA .NET | iOS | UWP | WebAssembly
Thursday, September 5, 2019 1:24:55 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, September 4, 2019

I recently blogged about the new support coming in CSLA 5 for Blazor. Shipping in .NET Core 3, Blazor is an HTML-based UI framework for WebAssembly.

There's another very cool UI framework for WebAssembly that sits on top of .NET: Uno Platform.

Uno Platform CSLA

This UI framework relies on XAML (specifically the UWP dialect) to not only reach WebAssembly, but also Android and iOS, as well as Windows 10 of course. In short, the Uno approach allows you to write one codebase that can run on:

  1. Any modern browser via WebAssembly
  2. Android devices
  3. iOS devices
  4. Windows 10

Uno is similar to Xamarin Forms, in that it leverages the mono runtime to run code on iOS, Android, and WebAssembly. The primary differences are that Xamarin Forms has its own dialect of XAML (vs the UWP dialect), and doesn't target WebAssembly.

Solution Structure

When you create an Uno solution you get a number of projects:

  1. A project with the implementation shared across all platforms
  2. An iOS project
  3. An Android project
  4. A UWP (Windows 10) project
  5. A wasm (WebAssembly) project

You can see a working example of this in the CSLA UnoExample sample app.

Following typical CSLA best practices, you'll also add a .NET Standard 2.0 Class Library project for your business domain types, and at least one other for your data access layer implementation. You'll also normally have an ASP.NET Core project that acts as your application server, because a typical business app needs to interact with server-side resources like databases.

It is important to understand that, like Xamarin Forms, the platform-specific projects for iOS, Android, UWP, and wasm have almost no code. They exist to bootstrap the app on each type of platform. This is true of the app server code also, it is just there to provide an endpoint for the apps. All the real code is in the shared project, your business library, and your data access library.

Business Layer

The purpose of CSLA .NET is to provide a home for business logic. This is done by enabling the creation of business domain classes that encapsulate all business logic, and that's supported through consistent coding structures and a rules engine.

To improve developer productivity CSLA also abstracts many platform differences around data binding to various types of UI and interactions with app servers and data access layers.

ℹ Much more information about CSLA is available in the free Using CSLA 2019: CSLA Overview ebook.

As a demo, nothing in the UnoExample is terribly complex, but it does demonstrate some very basic types of rule: informational messaging, warning messaging, and validation errors. It doesn't demonstrate things like calculated values, cross-object rules, etc. There's a lot more info about the rules engine in the CSLA RuleTutorial sample.

The BusinessLayer project has a couple custom rules: CheckCase and InfoText, and it relies on the Required attribute from System.ComponentModel.DataAnnotations for a simple validation rule.

The PersonEdit class relies on these rules to enable basic creation and editing of a "person" domain concept:

  [Serializable]
  public class PersonEdit : BusinessBase<PersonEdit>
  {
    public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(nameof(Id));
    public int Id
    {
      get { return GetProperty(IdProperty); }
      set { SetProperty(IdProperty, value); }
    }

    public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
    [Required]
    public string Name
    {
      get { return GetProperty(NameProperty); }
      set { SetProperty(NameProperty, value); }
    }

    protected override void AddBusinessRules()
    {
      base.AddBusinessRules();
      BusinessRules.AddRule(new InfoText(NameProperty, "Person name (required)"));
      BusinessRules.AddRule(new CheckCase(NameProperty));
    }
    
    // data access abstraction below...
  }

The PersonEdit class also leverages the CSLA data portal to abstract the concept of an application server (or not) and prescribes how to interact with the data access layer. This code also leverages the new CSLA version 5 support for method-level dependency injection:

    // properties and business rules above...

    [Create]
    private void Create()
    {
      Id = -1;
      BusinessRules.CheckRules();
    }

    [Fetch]
    private void Fetch(int id, [Inject]DataAccess.IPersonDal dal)
    {
      var data = dal.Get(id);
      using (BypassPropertyChecks)
        Csla.Data.DataMapper.Map(data, this);
      BusinessRules.CheckRules();
    }

    [Insert]
    private void Insert([Inject]DataAccess.IPersonDal dal)
    {
      using (BypassPropertyChecks)
      {
        var data = new DataAccess.PersonEntity
        {
          Name = Name
        };
        var result = dal.Insert(data);
        Id = result.Id;
      }
    }

    [Update]
    private void Update([Inject]DataAccess.IPersonDal dal)
    {
      using (BypassPropertyChecks)
      {
        var data = new DataAccess.PersonEntity
        {
          Id = Id,
          Name = Name
        };
        dal.Update(data);
      }
    }

As is normal with CSLA, any interaction with the database is managed by the data access layer, and management of private fields or data within the domain object is managed in these data portal methods, for a clean separation of concerns.

Data Access Layer

I am not going to dive into the data access layer (DAL) in any depth. The implementation in the sample is a pure in-memory model relying on LINQ and a static collection as a stand-in for a database Person table.

This approach is valuable for two scenarios:

  1. A demo or example where I want the code to "just work" without forcing you to create a database
  2. Integration testing scenarios where automated integration or user acceptance testing should be fast, and should be performed on a known set of data - without having to reinitialize a real database each time

This sample code isn't quite at the level to accomplish the second goal, but it is easily achieved, especially given that the DAL is injected into the code via DI.

App Server

The AppServer project is an ASP.NET Core project using the empty API template. So it just contains a Controllers folder and some configuration. It also references the business and data access layers so they are available on the hosting server (maybe IIS, maybe in a Docker container in Kubernetes - thanks to .NET Core there's a lot of flexibility here).

Configuration

In the Startup class CSLA and the DAL are added to the available services in the ConfigureServices method:

      services.AddCsla();
      services.AddTransient(typeof(DataAccess.IPersonDal), typeof(DataAccess.PersonDal));

And the Configure method configures CSLA:

      app.UseCsla();

It is also important to note that the app server is configured for CORS, because the wasm client runs in a browser, and isn't deployed from the app server. Without CORS configuration the app server would reject HTTP requests from the wasm client app.

Data Portal Controllers

The reason for the app server is to expose endpoints for use by the client apps on iOS, Android, Windows, and wasm. CSLA has a component called the data portal that abstracts the entire idea of an app server and the network transport used to interact with any app server. As a result, an app server exposes "data portal endpoints" using components supplied by CSLA.

In the Controllers folder are DataPortalController and DataPortalTextController classes. The DataPortalController looks like this:

  [Route("api/[controller]")]
  [ApiController]
  public class DataPortalController : Csla.Server.Hosts.HttpPortalController
  {
    [HttpGet]
    public string Get()
    {
      return "Running";
    }
  }

The Get method is entirely optional. I tend to implement one because it makes it easier to troubleshoot my web server. But the real behavior of a data portal endpoint is in its ability to handle a POST request, and that's already provided via the HttpPortalController base class.

The only difference in the DataPortalTextController is one line in the constructor:

    public DataPortalTextController()
    {
      UseTextSerialization = true;
    }

This is due to a current limitation of .NET running in WebAssembly in the browser: the HttpClient can't transfer binary data, only text data.

Normally the CSLA data portal transfers data as binary, often compressed. The whole point is to minimize data over the network and maximize performance. However, in the case of a wasm client app that binary data needs to be Base64 encoded into text for transfer over the network.

The result are two data portal endpoints, one binary, the other text. Otherwise they do the same thing.

Uno UI Apps

The remaining projects in the solution rely on Uno to implement a common XAML-based UI with apps for iOS, Android, Windows, and wasm. Each of these apps is called a "head", and they all rely on a common implementation from the UnoExample.Shared project.

Platform-Specific UI Projects

Each head project is a bootstrap for the client app, providing platform or operating system specific startup code and then handing off to the shared code for all the "real work". I'm not going to explore the various head apps, because they are template code - nothing I wrote.

⚠ The current Uno templates start with an Assets folder in the shared project. That'll cause compiler warnings from Android. Move that Assets folder from the shared project to the UWP project to solve this problem.

⚠ Do not update the console logging dependency in NuGet. It starts at version 1.1.1, and if you upgrade that'll cause a runtime issue with threading in the wasm head.

⚠ You may need to update the current target OS versions for Android and UWP, as the Uno template targets older versions of both.

Shared Project

The way Uno works is that you implement nearly all of your application's UI logic in a shared project, and that project is compiled and deployed via each platform-specific head project. In other words, the code in the shared project is compiled into the iOS project, and into the Android project, and into the Windows project, and into the wasm project.

The result, is that as long as you don't do anything platform-specific, all your UI client code ends up in this one shared project.

Configuration

When each platform-specific head app starts up it hands off control to the shared code as soon as any platform-specific details are handled. The entry point to the shared project is via App.xaml and any code behind in App.Xaml.cs.

CSLA is configured in the constructor of the App class. In the UnoExample code there are two sets of configuration, only one of which should be uncommented at a time.

Use Text-based Data Transfer for WebAssembly

As I mentioned when discussing the app server, the HttpClient object in .NET on WebAssembly can't currently transfer binary data. This means that CSLA needs to be configured to Base64 encode the data sent to the app server. In the constructor of the App class there is this code:

#if __WASM__
      Csla.DataPortalClient.HttpProxy.UseTextSerialization = true;
#endif

This uses a compiler directive that is predefined by the wasm UI project to conditionally compile a line of code. In other words, this line of code is only compiled into the wasm project, and it is totally ignored for all the other project types.

Run "App Server" In-Process

After that, the constructor configures CSLA to run the "app server" code in-proc on the client. This is useful for demo purposes as it means each app will "just run" without you having to set up a real app server:

      CslaConfiguration.Configure().
        ContextManager(new Csla.Xaml.ApplicationContextManager());
      var services = new ServiceCollection();
      services.AddCsla();
      services.AddTransient(typeof(DataAccess.IPersonDal), typeof(DataAccess.PersonDal));

CSLA is configured to use an ApplicationContextManager designed for Uno. This kind of gets into the internals of CSLA, but CSLA relies on different context managers for different runtime environments, because in some cases context is managed by HttpContext, others on a per-thread basis, and still others via static fields.

The use of ServiceCollection configures the .NET Core dependency injection subsystem so CSLA can inject the correct implementation of the data access layer upon request.

ℹ In a real app of this sort the data access layer would not be deployed to, or available on, the client apps. It would only be deployed to the app server. But this is a demo, and it is far more convenient for you to be able to just run the various head apps without first having to set up an app server.

Invoke a Remote App Server

For the UWP and wasm heads you can easily comment out the "local app server" configuration and uncomment the configuration for the actual app server:

      string appserverUrl = "http://localhost:60223/api/dataportal";
      if (Csla.DataPortalClient.HttpProxy.UseTextSerialization)
        appserverUrl += "Text";
      CslaConfiguration.Configure().
        ContextManager(new Csla.Xaml.ApplicationContextManager()).
        DataPortal().
          DefaultProxy(typeof(Csla.DataPortalClient.HttpProxy), appserverUrl);

This code sets up a URL for the app server endpoint, appending "Text" to the controller name if text-based encoding should be used.

It then configures the application context manager, and also tells the CSLA data portal to use the HttpProxy type to communicate with the app server, along with the endpoint URL.

⚠ This only works with the Windows and wasm client apps. It won't work with the iOS or Android client apps because they won't have access to your localhost. If you want to use an app server with the Android or iOS apps you'll need to deploy the AppServer project to a real app server.

Notice that there is no configuration of the data access layer in this scenario. That's because the data access layer is only invoked on the app server, not on the client. This is a more "normal" scenario, and in this case the client-side head projects would not reference the DataAccess project at all, so that code wouldn't be deployed to the client devices.

UI Implementation

I'm not going to walk through the UI implementation in great detail. If you know XAML it is pretty straightforward, and if you don't know XAML there are tons of resources out there about how UWP apps work.

The really cool thing though, is how Uno manages to provide a largely consistent experience for UWP-style XAML across four different platforms. In particular, I found building this example quite enjoyable because I could use standard debugging against the UWP head, and then just run the code in the wasm head. Usually that means the wasm UI "just works", and that's wonderful!

ℹ In the cases where I had difficulties, the Uno team is active on the Uno Gitter channel (like a public Teams or Slack), and between the team and the community I got over any hurdles very rapidly.

Loading List of People

The MainPage displays a list of people in the database, and has a button to add a new person. It also has a couple text output lines to show status and errors. I don't claim that this is a nice or pretty user interface, but it demonstrates important concepts 😊

The important bit is in the RefreshData method, where the CSLA data portal is used to retrieve the list of people:

    private async Task RefreshData()
    {
      this.InfoText.Text = "Loading ...";
      try
      {
        DataContext = await DataPortal.FetchAsync<PersonList>();
        this.InfoText.Text = "Loaded";
      }
      catch (Exception ex)
      {
        OutputText.Text = ex.ToString();
      }
    }

This demonstrates a key feature of CSLA: location transparency. The data portal call will work regardless of whether the data portal was configured to run the app server code in-process on the client, or remotely on a server. Even better, though this example app uses HTTP as a transport, you could configure the data portal to use gRPC or RabbitMQ or other network transports, and the code here in the UI wouldn't be affected at all!

ℹ When editing XAML or codebehind a page you might find that you get all sorts of Intellisense errors. This can be resolved by making sure the Project dropdown in the upper-left of the code editor is set to UnoExample.UWP. It'll often default to some other project, and that causes the errors.

In this example notice that the Project dropdown is set to UnoExample.Droid, and that is why the code editor is all confused.

Editing a PersonEdit Object

The EditPerson page is a typical forms-over-data scenario. As the page loads it is data bound to a new or existing domain object:

    public int PersonId { get; set; } = -1;

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
      if (e.Parameter != null)
        PersonId = (int)e.Parameter;

      PersonEdit person;
      this.InfoText.Text = "Loading ...";
      if (PersonId > -1)
        person = await DataPortal.FetchAsync<PersonEdit>(PersonId);
      else
        person = await DataPortal.CreateAsync<PersonEdit>();
      DataContext = person;
      this.InfoText.Text = "Loaded";
    }

The user is then able to edit the Name property, which has rules associated with it from the business library. Details about those rules (and other metastate about the domain object and individual properties) can be displayed to the user via data binding. The Csla.Xaml.PropertyInfo type provides data binding with access to all sorts of metastate about a specific property, and that is used in the XAML:

    <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <csla:PropertyInfo x:Name="NameInfo" Property="{Binding Name, Mode=TwoWay}" />
    <TextBlock Text="{Binding ElementName=NameInfo, Path=Value}" />
    <TextBlock Text="{Binding ElementName=NameInfo, Path=IsValid}" />
    <TextBlock Text="{Binding ElementName=NameInfo, Path=InformationText}" Foreground="Blue" />
    <TextBlock Text="{Binding ElementName=NameInfo, Path=WarningText}" Foreground="DarkOrange" />
    <TextBlock Text="{Binding ElementName=NameInfo, Path=ErrorText}" Foreground="Red" />

Again, I don't claim to be a UX designer, but this does demonstrate some of the capabilities available to a UI developer given the rich metastate provided by CSLA. The result looks like this:

Once the user has edited the values on the page, they can click the button to save the person. That also relies on CSLA to provide location transparent code:

    private async void SavePerson(object sender, RoutedEventArgs e)
    {
      try
      {
        var person = (PersonEdit)DataContext;
        await person.SaveAsync();
        var rootFrame = Window.Current.Content as Frame;
        rootFrame.Navigate(typeof(MainPage));
      }
      catch (Exception ex)
      {
        OutputText.Text = ex.ToString();
      }
    }

The SaveAsync method uses the data portal to have the DAL insert or update (or delete) the data associated with the domain object. In this case, once the object's data has been saved the user is navigated to the list of people.

Conclusion

I am very excited about WebAssembly and the ability to run native .NET code in any modern browser. The Uno Platform offers a powerful UI framework for building apps that run native on mobile devices, in Windows, and in any modern browser.

CSLA .NET has always been about providing a home for your business logic, allowing you to write your logic once and to then leverage it on any platform or environment supported by .NET. Thanks to .NET running in WebAssembly, this means that you can take your business logic directly into any modern browser on any device or platform.

Android | CSLA .NET | iOS | UWP | WebAssembly
Wednesday, September 4, 2019 10:07:18 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, April 26, 2016

thHU21A440There’s a lot of speculation at the moment, mostly I think from the tech press, that there’s no future for Windows 10 Mobile (aka Windows Phone). To the point that Terry Myerson apparently released a statement to clarify that Microsoft is committed to mobile for many years.

Over the past couple years I’ve been increasingly critical of Microsoft’s mobile strategy as well – it is hard not to be when the platform has such low market share, there’s been a lack of flagship devices released, and there’s still a major issue with apps (that don’t exist or that are quite poor compared to iPhone/Android versions).

So at the beginning of this year I “threw in the towel” and switched to the iPhone. This was after talking to a lot of people in person and via twitter about whether to go iPhone or Android. The overwhelming advice was that if you live in the US you should go iPhone, so I did exactly that.

After a couple weeks with the iPhone I wrote a comparison between Windows 10 Mobile and the iPhone – from my perspective. I’m selfish – I’m looking for a good answer for me, so my blog post was about me and my personal experience. After a couple more months I realized that this is a real tradeoff, because Windows 10 Mobile the operating system is more consistent and polished than iOS, but the apps on the iPhone are almost universally superior.

At that point I thought I’d try Android. This was right after Microsoft Build 2016, where it seemed like there was a lot of love for Android, and where I encountered a whole lot of my peers who were incredulous that I had an iPhone instead of an Android (where they were last fall when I was soliciting input I have no idea – I begin to suspect that people only advocate for their platform when you have “the other platform” in your pocket). Basically, some of the iOS frustrations and inconsistencies were bugging me enough I wanted to look elsewhere.

I didn’t even last a couple weeks on Android though. I bought a OnePlus 2 – a high-end device with very generic Android. It turns out that generic Android pretty much sucks – much like generic Linux. You need to spend (in my experience) hours and hours and hours researching and trying different launchers, lock screen apps, email apps, calendar apps, contact apps, etc. Just to get basic functionality that works out of the box in the iPhone and Windows 10. O.M.G. I don’t understand how people can waste that much time just getting the basics to work on their phones!?!

Now I’m back to Windows 10 with a Lumia 950xl. And I’m happy.

I keep hearing how Windows “lacks polish”. Clearly this statement is being made by people who have not actually used Windows 10, iOS, and Android back to back like I just did. In some ways iOS might have more polish, but it is far, far less consistent than Windows, so I give the OS polish nod to Windows 10. Android isn’t even in the running – it has no polish or consistency – though maybe with another many hours of research and testing I could have found a launcher that I liked? That’s not how I want to spend my life.

I also keep hearing about the Windows “app gap”. That is obviously a real problem. It is absolutely the case that the iPhone has a lot more apps, and almost all the apps are superior. It is also the case that the Android apps are plentiful, but they generally look like crap compared to their iOS counterparts. But I’ll give it to Android that, though its apps are inconsistent and often cartoonish, they are full featured, unlike Windows apps.

One other note on apps: Android is clearly designed to work well if you are a Google user (mail/calendar/contacts) and it is pretty half-baked for people not on Google. I can’t say I support the EU going after Google any more than I did when they went after Microsoft so long ago – I think that’s just dumb – but at the same time, I understand their consistent view here, because Google is using Android to drive usage and lock-in around their cloud service offerings, not unlike what Microsoft did 20 years ago with Windows.

Finally, I keep hearing how Windows phone hardware is inferior. I even heard that from someone at Microsoft. I’m skeptical. It is true that the iPhone 6s is a really nice device, and I love the fingerprint unlock feature. Android device quality varies a lot, but the OnePlus 2 is pretty nice (if a bit heavy) and has a fingerprint reader (if you can find a lock screen app that supports it). The Lumia 950 is nicer and lighter than the Android devices I’ve seen and used (including the Samsung ones). But I’ll grant that it isn’t as nice as the iPhone. At the end of the day though, I think all three platforms have hardware that are basically in the same ballpark: reasonably stylish, light, fast, with decent battery life, and great cameras. If it was just down to hardware my ranking would be iPhone 6s, Lumia 950, Samsung Android, other Android – in that order.

At this point though I’ll remind you that I’m selfish here – I’m after a solution for me.

That means it comes down to iPhone vs Windows 10 Mobile – the Android OS is too unpolished, clumsy, and inefficient; and its apps are too ugly, inconsistent, and cartoonish. It is clearly the cheapest platform, and you get what you pay for. I’m willing to pay to get a more productive experience.

And at the end of the day there are only 3 apps that don’t exist or don’t work on Windows that I actually need: Swarm, Waze, and the Parrott Bebop app for my drone.

My bank does have an app on iPhone/Android, but it sucks and so not having it isn’t really a loss. To solve my bank app issue I need to switch to a better bank, not a different phone.

I weighed the value of those 3 apps against Windows 10’s more polished and consistent OS experience; and I considered that Siri is like Cortana’s dullard older sister (yes, Siri is really an idiot compared to Cortana, and Cortana on the iPhone is crippled compared to Windows or Android).

Ultimately I’ve decided that I’d rather go with the best OS on a regular basis. In my case I’m fortunate enough that I can carry a second phone (sans SIM) so I can still fly my drone – it just needs the app and wifi after all. That also gets me Waze and Swarm, because they also work over wifi, and my Lumia works great as a wifi hotspot when I’m out and about.

At the end of the day, until Foursquare, Google, and Parrot (and my bank) get their heads out of their @$$’s I am working around them via a two phone solution.

But most importantly, I’m happy using Windows 10 and Cortana for my 99% use case of email/calendar/phone/text/messaging/Office/etc.

And fwiw, I think the continued rapid adoption of Windows 10 itself (on my Surface and Desktop for example) will drive more and more companies to create UWP apps – perhaps not initially for the phone, but at least for the 300 million (and climbing) people running Windows 10. The thing is, once your app runs in UWP, getting to the phone is a pretty small step – and one companies would be foolish not to do for such little effort.

Tuesday, April 26, 2016 3:46:05 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, July 14, 2014

From around 1995 until 2010 there was really only one operating system for client computing: Windows.

Prior to 1995 there were a lot of options, though most not recognizable to users today: 3270 terminals, VT terminals, OS/2, Windows, DOS, CPM, and a bunch of others. Now most of these weren’t “client computing”, they were relatively dumb terminal technologies that provided access to a server (back then called a mainframe or minicomputer). Very much like today’s web browser (sans JavaScript).

Today we’ve returned to a chaotic landscape of client computing: browsers, Windows, iOS, OS X, Android, Linux (for the daring), and of course it isn’t like the pre-1995 technologies went away, they are just mostly emulated in Windows. What is interesting though, is that most of today’s client computing technologies do actually enable smart client software development. This includes the browser which can be used as a smart client technology via JavaScript development, even though the majority of browser “apps” are actually just colorful versions of 1990-era terminal-based computing where the processing is all on a server/mainframe/minicomputer/whatever-you-want-to-call-it.

What is interesting about this return to client-side chaos is that it has reopened the door for third party developer tools as a niche market.

In the early 1990’s there were quite a number of companies selling developer tools for other company’s platforms. Borland with C++, Delphi and TurboPascal, Gupta with SqlWindows, Powerbuilder, and a lot more.

When Windows became the dominant client computing platform most of these dev tools fell by the wayside (not that they went away, they just stopped being mainstream). This was because they couldn’t compete with Microsoft’s dev tools, which were always in sync with the platform in a way that was probably too expensive for third parties to match.

I think it is notable that our return to client computing chaos (or pluralism?) today has already led to numerous third party dev tool vendors that sell dev tools for other company’s platforms. Xamarin, PhoneGap, Telerik’s tools, and a lot more.

What is different to me is that in the early 1990’s I thought it was pretty obvious that Windows would become a dominant platform, and I tended to argue against using third party dev tools because I thought they’d have a rough go of it. As cool as Delphi was, I always recommended VB.

Today I’m not so sure. I don’t see any of today’s platforms becoming dominant in the foreseeable future. It is hard to imagine Windows returning to its monopoly status, but I can’t imagine iOS or Android or OS X displacing Windows as the primary corporate desktop computing environment either.

As a result we business developers need some way to build software independently of any particular platform or OS vendor, because we must assume all our business software will need to run on multiple platforms and OSes.

So today I find myself in the inverse of my early 1990’s stance, in that I’m reasonably convinced that building smart client software (at least for business) means using third party dev tools from vendors that aren’t tied to any one platform.

Of course I’ve spent the last 14 years in the .NET world, so naturally I gravitate toward a combination of Xamarin and Microsoft .NET as a way to use my C# and .NET knowledge across all platforms. I get to develop in Visual Studio on Windows where I’m most comfortable, and my resulting software runs on Android and iOS as well as on Windows Desktop, Phone, and WinRT.

As far into the future as I can see there’s no obvious platform/OS “winner”, so as a developer the question isn’t which platform to target, it is which third party dev tool reaches all platforms with a solid strategy that will stand out and thrive over the next many years.

Monday, July 14, 2014 1:00:31 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, March 17, 2014

I just created a release of CSLA 4 version 4.5.580-Beta with preliminary support for iOS via the Xamarin tools.

You can get it via nuget (easiest), or from the release page on GitHub.

This is an exciting pre-release because it now means you can reuse the same business logic code across all modern app client platforms and the desktop and the cloud. This is a “who’s who” list of supported platforms:

  • iOS
    • iPad
    • iPhone
  • Android
    • Phones
    • Tablets
  • Windows
    • WinRT (Windows 8)
    • WPF
    • Silverlight
    • Windows Forms
  • Windows Phone
  • Cloud and servers
    • Windows Azure
    • Windows Server
    • ASP.NET (MVC and Web Forms)
    • WCF
    • Web API
  • Linux
  • OS X

CSLA .NET allows you to easily create reusable business logic (authorization, validation, calculations, etc.) and to share a common app server with simple network configuration. I don’t know of any other open source C# framework that makes it possible for you to reuse the exact same business logic across all these different platforms.

Because the iOS support is new we are asking for your help. If you have the Xamarin tools for iOS please help us out by building some business code using CSLA and let us know if you find any issues (either on the forum at http://forums.lhotka.net or via the CSLA GitHub page.

Monday, March 17, 2014 10:42:21 PM (Central Standard Time, UTC-06:00)  #    Disclaimer