Rockford Lhotka's Blog

Home | Lhotka.net | CSLA .NET

 Thursday, 10 December 2015

Starting with version 4.6.300 CSLA .NET supports ASP.NET 5 (.NET Core) and the CSLA-Core NuGet package includes a portable class library that targets .NET 4.6 and dnxcore50.

There does appear to be an issue with adding the NuGet package to an ASP.NET Class Library project. I assume this is due to the pre-release nature of the ASP.NET 5 tooling.

What happens is easy to replicate. Create an ASP.NET 5 web site project, then add a portable class library using the ASP.NET 5 template:

snip_20151210110307

Then add a NuGet reference to CSLA .NET 4.6.300 (currently also in pre-release):

snip_20151210110454

Then try to use features of CSLA – for example, altering the Class1 code like this:

using System;
using Csla;

namespace ClassLibrary1
{
   [Serializable]
    public class Class1 : BusinessBase<Class1>
   {
         public Class1()
         { }
   }
}

The project will not compile at this point even though one would expect that CSLA really has been referenced:

snip_20151210110903

After some experimenting I found what appears to be a solution. The project.json file must be manually edited so CSLA is listed as a dependency not only in the “net451” framework, but also in the “dotnet5.4” framework:

{
   "version": "1.0.0-*",
   "description": "ClassLibrary1 Class Library",
   "authors": [ "Rockford" ],
   "tags": [ "" ],
   "projectUrl": "",
   "licenseUrl": "",
   "frameworks": {
     "net451": {
       "dependencies": {
         "CSLA-Core": "4.6.300-Beta001"
       }
     },
     "dotnet5.4": {
       "dependencies": { 
         "Microsoft.CSharp": "4.0.1-beta-23516",
         "System.Collections": "4.0.11-beta-23516",
         "System.Linq": "4.0.1-beta-23516",
         "System.Runtime": "4.0.21-beta-23516",
         "System.Threading": "4.0.11-beta-23516"
       }
     },
     “dependencies” : {
         “CSLA-Core”: “4.6.300-Beta001”
     } 
   }
}

The solution/workaround is to move the “CSLA-Core”: “4.6.300-Beta001” dependency from the “net451” framework to a global dependencies section.

With this change the project will now build.

Thursday, 10 December 2015 11:31:33 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, 09 December 2015

LVSPK25

It is time to register for VS Live or Modern Apps Live (register for either and get access to both!) in Las Vegas, March 7-11, 2016.

(I had to really concentrate to type 2016 – a whole new year already!!)

This is going to be a great set of conferences, co-located at Bally’s right as exciting new things like .NET Core and ASP.NET 5 are coming available.

Register with this link and save $500 off the standard price.

Visual Studio Live! includes content across the spectrum of mobile, Windows, web, and services development, with a healthy dose of ALM, TFS, and other cool tools.

Modern Apps Live! provides a unique conference experience, walking through every aspect of modern app development for iOS, Android, single-page web apps, and Windows, with an Azure-based backend, discussions about managing distributed teams, continuous integration, building code for testability, and wrapping up with great content around data analytics. If you want the end-to-end story on how to successfully build a modern cross-platform app this is the conference for you.

I look forward to seeing you in Las Vegas!

Wednesday, 09 December 2015 14:02:47 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, 02 December 2015

I think this article about Apple's attempt to transform the iPad into a laptop - and contrasting it to Microsoft's Surface-based attempt to transform a laptop into a tablet - is quite good.

Personally I'm a strong advocate for the hybrid device scenario, having spent the last few years entirely in Surface-land. Starting with the Surface Pro 3 (SP3) I have been quite happy with that choice. The SP1 and SP2 widescreen concept was interesting, but impractical for doing real work like editing documents or running Visual Studio. The SP3 and now SP4 screen sizes are very practical (especially the Surface Pro 4 - what a beautiful screen!!).

The idea that Apple would create some sort of hybrid was a foregone conclusion from my perspective - once I'd become hooked on using a Surface instead of an old-fashioned laptop.

When I'm sitting in a cramped airplane seat, or relaxing on the couch in front of the TV I want a tablet - one with all my stuff on it.

And when I'm trying to actually compose an email, write a document, or do some coding, I want a laptop - one with all my stuff on it.

Interestingly enough, "my stuff" is the same at all times. I want access to all my stuff whenever and wherever I am.

I use OneDrive to store all my documents, music, photos, etc. All my files are on my desktop, Surface, and in the cloud – so they are available anywhere and everywhere. And that would be true on a Mac and iPad too (though probably not offline on the iPad, so not accessible on an airplane?).

Another big reason my stuff is always available is because of the way Windows 10 roams everything - all my app/browser/desktop settings sync across my devices. And that could maybe be done between a Mac and iPad I would guess - with some effort to address the mismatch between Mac and iPad apps that do similar things, but aren’t the same apps.

But on Windows 10 I am using the same apps on my desktop and Surface (and often my phone). So there's no mismatch, they are literally the same.

Maybe not everyone values this consistency like I do - but I want my same browser with my same favorites/shortcuts/etc. on every device I use. And I want my news reader (NextGen Reader) and Reddit  (Readit) and weather and twitter (Tweetium) and Facebook apps to know what I've done and what I like without having to tell every device the same stuff over and over.

So yeah, I'm a big fan of the hybrid model - and I hope Apple is reasonably successful at it, if for no other reason that competition will drive Microsoft to keep making Win10 and Surface better and better so I love it more and more :)

Wednesday, 02 December 2015 13:16:16 (Central Standard Time, UTC-06:00)  #    Disclaimer

I have had my new Surface Pro 4 for a few days now (I waited to get the i7 model) and I’m liking it quite a lot. I really liked my SP3, and the SP4 is better yet.

My one primary disappointment is with the dock. I got the new Surface dock and tried to connect it to my two external monitors using brand new mini-DisplayPort-to-DVI cables but the displays were just all messed up – one or the other would come on but not both, and everything was very unstable.

Searching around the Internet I found this: https://www.reddit.com/r/Surface/comments/3s655j/surface_pro_4_dock_cannot_drive_a_dvi_monitor/

In summary, the Surface dock can’t power DVI or HDMI outputs directly. I assume it can power VGA directly, but I don’t know – maybe not?

This makes the dock pretty useless for many (most?) of us who don’t have monitors that have DisplayPort ports. I’ve never owned such a monitor and I don’t think I’ve ever actually seen one in a store or anything. So I assume that most of us don’t have such a thing.

WP_20151201_16_05_46_ProIn my case I was “fortunate” in that I’d already bought a powered DisplayPort hub to get the dual monitor scenario working from my Surface 3 dock, so that’s what I’m using to get my monitors to work. The DP hub I’m using is from StarTech and seems to work quite nicely.

The fact that it works remains quite disappointing though. The Surface dock looks like it would be useful, but in practice I think for most of us it doesn’t do what any reasonable person would expect – which is to say that the two DP ports are not what they seem.

So if you are considering buying the Surface dock I’d suggest that you also budget an extra US$100 or so to buy a DP hub and appropriate DP-to-DVI (or HDMI) cables.

Wednesday, 02 December 2015 10:49:22 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, 13 November 2015

Yesterday I got involved in a twitter discussion about the need for more women speakers (and attendees for that matter) at tech conferences. Of course twitter isn’t a good venue for discussing complex issues, and so I thought I’d put some of my thoughts into a blog post.

I identify as an ally for women in tech. I’m a technologist, but not a woman, so I can only express my views from being adjacent to the actual problem space. As such it is quite possible that my views are naïve in some ways, and if so I’ll beg forgiveness in advance (and welcome constructive feedback!).

I’m also a long-time co-chair for Visual Studio Live! and am the chair for Modern Apps Live!, and have spoken at hundreds of events around the world over the past couple decades. As a result I do have some perspective on how conferences work, the economics behind them, and the work involved in soliciting and selecting content for conferences.

To start with, I absolutely think that we need more women in technology, and (from my personal perspective) in software development. Nearly half the brainpower, creativity, and talent in the US is effectively untapped and that’s simply unconscionable.

One way to help get (and retain) more women involved in technology is to have women be visible as leaders in our industry. Not just business leaders like Marissa Mayer, but actual technologists who are visible within our communities.

As an aside, business leadership is great, but doesn’t translate to credibility in the minds of most technologists. I think one of our challenges in this space is that a lot of women feel pushed out of technology and into tangential careers such as project management, business analysis, sales, or pure business. That might be good for them as individuals (if they love that other career more than technology), but it doesn’t help the lack of women in technology.

For technologists some of the most visible people in the industry are public speakers at conferences and similar events. Many regular speakers are (as my wife puts it) “famous in geek-land”, and as such are a type of role model for others in the industry. So it is a logical thought progression to think that one way to encourage more women to get involved in software development is to get more women to be regular, recognized speakers at conferences.

In the twitter discussion I referenced at the start of this post the premise of the original post was addressing some of the primary barriers to women attending or speaking at industry events.

snip_20151113125613

Some of this is (imo) gender-neutral. As a professional (or at least semi-professional) speaker I expect events to cover my travel costs and provide a stipend or speaker fee. I provide a valuable professional service, and as such I expect reasonable compensation. That should be true regardless of anyone’s gender.

The childcare point might at first seem a bit odd to people who haven’t been paying attention to these issues. But it is a primary challenge when talking about getting women to attend or speak at events. For better or worse, in the US it is still assumed to be the mother’s responsibility to manage childcare for any kids – whether we’re talking single mothers or a married couple.

To be clear, this isn’t a universal truth – there are women who have a spouse/partner willing to assume childcare responsibilities while they are at an industry event – but like it or not there are a lot of women who don’t have that support, or who are single mothers without that option.

On the surface it seems obvious to lump “childcare” into the “travel cost” category – put the burden of such cost entirely on the speaker-who-is-a-parent. I do think though, that this cost tends to fall mostly on women, and that it absolutely contributes to the lack of women in technology and at conferences. There’s value to conferences in having more diversity – more talented people available as speakers. And there’s value to our industry as a whole to tapping into all the underutilized brainpower of women would otherwise be engaged in the field. As a result, perhaps there’s some way to translate the value to the industry and conferences into schemes that help absorb some of the costs or complexities involved in childcare for the kids of speakers.

No matter how you look at it, at the end of the day this is ultimately a matter of economics for the event organizer and the speaker: it costs X to go speak at an event, so as a professional I should expect Y from the conference organizer.

Before going further I think it is important to consider a couple things about events in our industry, and also the broader motivations of many (most?) of the regular speakers that I’ve interacted with over the past couple decades.

At least in the Microsoft software development event space there are some broad categories of events, each with their own economic model.

  1. Local/regional community events – user groups, code camps – which are generally free to attendees and which generally provide no direct compensation to speakers because they have no budget
  2. Local/regional commercial events – Heartland Developer Conference, That Conference, etc. – which are organized by a someone as part of a commercial or marketing venture (even if their intent is to support the community, their venture itself involves charging attendees and paying expenses, or indirectly making money by marketing the event under their company name)
  3. Large independent industry events – VS Live, Dev Intersections – which are organized by someone as a commercial venture where attendees pay to attend
  4. Microsoft direct industry events – Ignite, Build – where Microsoft organizes events and charge attendees to attend, and where Microsoft also largely controls the content with the intent of delivering the “official” marketing message around their products and services

There are outliers that don’t fit these categories and grey areas between them, but these are very common models.

Next I think it is important to consider the value a speaker gains from speaking. Different speakers put different weight toward these items, but they all should be considered part of the package.

  1. Travel expenses covered – should it cost money for the speaker to get themselves there to speak?
  2. Speaker stipend or fee – should the speaker be compensated for their work?
  3. Travel to cool places – sometimes events are in interesting/fun places around the world and the speaker might perceive value in such travel
  4. Speaker community – regular speakers on a circuit often become good friends, and only see each other at events, and some speakers perceive value in the opportunity to see their friends in person from time to time
  5. “Do good” – some speakers get a great deal of personal satisfaction by helping their colleagues be better technologists – altruism is a real thing
  6. Publicity/fame – translates to marketing value for the speaker and/or their employer – I’m talking about passive marketing here – speakers generate publicity by speaking, that’s just reality, and that publicity often helps them sell books, drive traffic to their blogs, get leads for subsequent training/consulting work, etc. This only happens (as a general rule) if the speaker provides great high-quality content without any overt marketing or product message – conference organizers and attendees love this stuff!!
  7. Direct marketing opportunity – usually this occurs because the speaker (or their employer) spent a metric ton of money to be a high-level sponsor of the event and thus basically bought a speaking slot – and in this scenario one would assume the speaker (or their employer) is making it worth the speaker’s time/effort to deliver their content. In many cases this is frowned upon by attendees, but sometimes this is the point of speaking – and in the case of first-party events like Ignite/Build the content is often quite good even as it is structured to fit within the overall marketing message of the event

Now here’s where it gets interesting because individual speakers weigh these benefits differently, and conference organizers do as well. I don’t know that it is possible to generalize the intersection between value to the speaker and what’s offered by various events. Instead I’ll relate some of my personal decisions from my experiences.

I generally won’t speak without some compensation. John Scalzi says it quite well. Mostly I expect that compensation to be in the form of a speaker fee, over and above travel expenses. To be honest, it is a rare thing that my speaker fees amounted to “real money”, at least by comparison to my salary or a typical consulting fee. Anyone who thinks they are doing to speak at tech conferences as a money-making career are generally delusional.

I do know a couple people who do make their living speaking, but they get paid by some company like Microsoft to do high-end presentations to decision makers (AKA CxO level people with big budgets), and if they speak at a more normal tech event it is as the highly paid keynote speaker. Yes, there’s a big difference in compensation between keynote speakers and regular session speakers at commercial events. And it is important to recognize that these are highly experienced speakers, not people just getting started in their careers as technologists or presenters.

I have spoken at some events because it was in the interest of Magenic to do so – so my compensation was from my employer rather than from the conference organizer. And I’ve spoken at some events because it was in the interest of Microsoft to do so – so my compensation came from a patron/sponsor rather than from the conference organizer.

I’ve also spoken at some events where all they covered was travel expenses without any actual speaker compensation. When I’ve done this it was because I had ulterior motives for getting to the event or the location of the event. As a result, I’ve been to some pretty cool places around the world. Basically I got free access to somewhere I’d have otherwise needed to pay my own way.

In all cases I try to deliver high quality content tailored to the audience. And in all cases my hope is that people will find the content, and my delivery, interesting and enjoyable enough that they’ll consider further action, such as:

  1. Giving me good speaker reviews (so I get more speaking opportunities)
  2. Reading my blog (where I have ads that generate revenue)
  3. Buying my books (where I make money)
  4. Hiring Magenic to do some consulting (which benefits my employer, and thus me)

Like writing technical books, speaking at technical conferences is best viewed (imo) as one piece of a broader set of activities – all of which generate some amount of revenue, and the totality of which, taken together, amounts to a decent living.

To bring all this back to women speaking at conferences, I strongly suspect these same motivations apply regardless of gender. My female friends/colleagues who speak in the same circuits as me get the same compensation as I do, and the fact that they’ve been speaking for many years implies (to me) that they are getting value beyond the speaker fees. They are mostly consultants or business owners or authors too, so as in my case I’m sure most of the value of speaking is to generate reputation that translates into business leads, book sales, etc.

I’d like to set up a straw-man for the purposes of discussion. Dangerous, but I think valuable as long as we all remember that these are educated guesses in terms of numbers. Also, I’m going to focus primarily on commercial events, not community/local events where most people speak for “love of community” – a euphemism for free.

Let’s assume the event pays $500/talk at a commercial event. A made-up value, but not entirely out of line in my experience. And most events that fly speakers in try to have each speaker deliver 2-3 talks.

It isn’t cost-effective for anyone to have a speaker deliver just one talk, and there’s risk to the event itself if a speaker delivers 4+ talks (suppose they get sick, or just don’t show up, or it turns out they really suck as a speaker).

This means most speakers will bring in around $1000 for speaking at a commercial event.

Next consider the cost of a speaker flying to an event.

  • Flight: $350
  • Hotel: $200/night x 2 nights: $400
  • Parking/taxi/etc: $250

These are made-up values, but probably pretty realistic for a frugal traveler: total cost of $1000. Some events pay more or less of a stipend, and some do/don’t cover flights or hotel or …  Again, generalizations are hard because everyone seems to do their own thing. But the overall cost structure is probably accurate at around $1k per speaker.

If the speaker pays their own travel and gives two talks they break even. If the event covers some/all of the travel cost then the speaker actually gets to pocket some money as direct compensation.

I’m not a lawyer or tax person, but everyone should also consider (at least in the US) that speaking is a job, and if you are doing it on your own then it is your business and that means you can deduct expenses from your taxes. This probably doesn’t apply if your employer is paying for you and they keep any speaker fees – but if you as a speaker are paying your way and accepting the compensation, then you are running a business and can deduct those expenses – thus reducing their effective cost by some percentage.

As I implied earlier, if this were 100% about direct compensation for speaking at conferences nobody would ever speak at conferences. From a purely personal economic perspective it is far, far, far better to spend a week billing at consulting rates than to pretend you are “making money” by speaking at a conference. The real value of speaking at conferences is almost entirely in the indirect value – the consulting/training leads it generates, the books it sells, the traffic it drives to your blog, etc.

snip_20151113220705Regardless, now consider adding cost for childcare. I don’t know exactly what that costs, though I do know the cost varies greatly by region in the US. According to a quick search apparently it is around $50/day on average, but that’s probably if you have a long-term contract. Drop-off services for a day I would guess cost more – so $100/day per child?

I’m assuming the children are coming with the parent, so this childcare would be somewhere local to the conference. Conferences are usually at hotels, sometimes at convention centers. Rarely near where I’d expect to find a childcare facility, so there’d be the need for a rental car or Uber or something to get to/from the childcare facility. I’m thinking rental car might be cheapest, since there’d be at least two round-trips per day. Between a rental car and typical hotel parking fees let’s call this $100/day.

Finally, because the children are coming with the parent there’s the added airfare. Airfare is tricky, but sticking with my earlier $350 guess the cost is $350 per child.

For one child where the parent gives all their talks on one day this is around $550. For two children it is $1000.

This is a major burden for a parental would-be speaker to assume – no wonder it is hard to get women to speak (or attend) conferences!

One solution, for a parent who has a spouse/partner, is for their partner to take care of the child(ren). I’ve been extremely fortunate in my career because my spouse did exactly that (thank you honey!). Sadly the reality is that this isn’t a common scenario for most mothers – their partners generally can’t or won’t assume role of caretaker at this level. It is also the case that (at least in the US) there are a lot of single mothers who don’t have the option at all, because there’s no spouse/partner available at all.

Another solution is that there’s some way to offset this cost in whole or part. The obvious thought is that event organizers can just provide childcare, or absorb the costs associated with childcare.

Non-commercial events may have alternatives, because they usually don’t have the budget to pay anything to start with, but instead often live and die based on corporate sponsorships. I’m left wondering if code camp organizers (for example) couldn’t solicit sponsorship from local childcare chains in their area? Perhaps set up a “kids corner” on a Saturday so speakers (and attendees?) could drop off their kids for a while – at the event – with supervised/insured and donated childcare. The value proposition for the childcare company seems clear: good marketing to a group of parents that make good money and need childcare.

I feel reasonably safe in suggesting that the organizers of commercial events are unlikely to absorb the cost outright, because their purpose behind running the events is to make money. In the twitter thread someone mentioned that one way to offset the cost would be to reduce food/beverage service for attendees. Another way would be to increase the cost of the conference for attendees.

fwiw: having watched a conference basically drive itself into the ground by providing crappy food/entertainment for attendees I don’t think cutting that part of the conference experience is a viable long-term strategy – people won’t pay the going conference rates to attend a conference with crappy food and/or no coffee/snacks between sessions.

In the end though, I think there may be two obvious/primary paths for women to enter the speaking circuits.

One is by working for one of the larger companies that put on first party events. Basically we’re talking about Microsoft, Apple, Google, and other companies that put on events and many/all of the speakers are their employees. Within that context speakers are compensated (and childcare is covered) under that company’s employment policies. The good news is that there’s increasing pressure on those companies for equality of pay and to enable diversity in their employee bases.

That said, I’m unaware of companies that pay for parents to bring their kids along with on trips or cover their childcare while on the road. Perhaps this should become a thing?

A second is to do what most of us have done: start by speaking at local events (and/or write a book), build up enough of a reputation as a speaker to get speaking slots at regional events, and then get selected as a speaker at larger industry events.

As I mentioned earlier, perhaps for non-commercial events the idea is to get sponsorships from childcare companies. For commercial events perhaps the event organizers need to pay all speakers more, or even come up with some mechanism by which they are able to help offset the costs of some barriers to becoming a speaker, such as the costs of childcare?

This is where the rubber meets the road, and I don’t personally have a clear answer. I’d love to hear ideas on how to help offset the costs of being a parent and a speaker at the same time.

Friday, 13 November 2015 22:31:00 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, 06 November 2015

.NET Core is somewhat confusing to a lot of people. In short, .NET Core is an open source reimplementation of .NET that Microsoft has been, and continues to, work on completing. The Universal Windows Platform (UWP) runs on .NET Core, as does the upcoming ASP.NET 5 technology. What is a little confusing is that ASP.NET 5 also runs on full .NET 4.6 – it can run on either NET implementation.

One of the biggest things to understand about .NET Core is that Microsoft is working hard to keep it very modular. Unlike full .NET, where a lot of things are in a few assemblies, in .NET Core there are a lot of assemblies with a few things in each. And those assemblies are generally available via NuGet, not included by default as part of the “.NET Core install”. The advantage to this is that your app can be more lean, because generally we’ll bring in only the framework assemblies we need, where in full .NET a lot of unneeded stuff tends to just come along for the ride.

Getting to UWP

Some time ago I added Windows 10 UWP support to CSLA .NET, which means that I already did some work to get CSLA running on .NET Core. However, the UWP project template in Visual Studio is somewhat forgiving, in that it brings in several .NET framework components that aren’t automatically brought in if you create a bare-bones .NET Core class project. This makes sense, because there are a set of assemblies necessary to support UWP and I think we’d all expect those to be automatically available to any UWP project.

The CSLA UWP project targets Windows 10.

snip_20151105231251

Or in project.json terms:

{
  "dependencies": {
    "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
  },
  "frameworks": {
    "uap10.0": {}
  },
  "runtimes": {
    "win10-arm": {},
    "win10-arm-aot": {},
    "win10-x86": {},
    "win10-x86-aot": {},
    "win10-x64": {},
    "win10-x64-aot": {}
  }
}

Back in the Windows 8 timeframe we did a bunch of work to support the Wiindows Runtime (WinRT). WinRT is quite a lot like Silverlight, in that apps run in a sandbox and have access to a subset of .NET. So getting CSLA running for WinRT wasn’t too hard because we already supported Silverlight before Windows 8 came along. However, WinRT changed reflection in some pretty radical ways, and we had to do quite a lot of work to replicate the old-style reflection API and behaviors in the WinRT world.

UWP now runs on .NET Core, which is a reengineered subset of full .NET, and UWP apps use the WinRT API from a UI perspective. So really UWP apps are very comparable to WinRT apps. That said, Microsoft did take this opportunity to yet again tweak reflection, so I used the WINDOWS_UWP compiler symbol to provide UWP-friendly implementations of the reflection fixes we’d created for WinRT. Whew!

snip_20151105232029

(to be honest, some of the code in the TypeExtensions class are basically placeholders that need more work to be complete; for example: TypeExtensions.GetConstructor is not implemented properly)

The final thing to understand about the existing UWP support is that .NET Core code can be compiled to native – in fact it will be compiled to native by the Windows Store to provide the end user with the best performance. Compiling .NET code to native is a fairly complex process and one part of that process is that the end result only contains the code that is known to be invoked – all other code is literally left out of the end result. If you don’t use reflection this is not a problem, but if you do use reflection (and CSLA does) then it is important to tell the native compilation process not to “optimize” away code you might actually be calling.

To do this you edit a file in your UWP application’s Properties folder called myapp.rd.xml. In this file you indicate the assemblies that shouldn’t be optimized. For example:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Library Name="Csla.Uwp">
    <Assembly Name="Csla" Activate="Required All" Browse="Required All" Serialize="Required All" Dynamic="Required All" />
  </Library>
</Directives>

This says that Csla.dll shouldn’t be optimized away – which is probably fine because it isn’t very big to start with. And you absolutely must ensure that your business assemblies aren’t optimized because CSLA reflects against your business assemblies to do its work. Again, probably not a big deal because your business assembly should be containing business code and not UI assets or other large artifacts – in other words it shouldn’t be terribly large either.

This is done in your UWP app project – the one that gets built and deployed to the user – and the one that typically references your business assemblies and CSLA.

Getting to .NET Core

Given everything I just discussed regarding UWP, it seems like getting a “pure” .NET Core assembly for CSLA wouldn’t be too hard. But there were some unexpected hurdles I’ll discuss.

The first step to creating a class library project for .NET Core is to create a portable class library (PCL) project that targets .NET 4.6 and ASP.NET Core 5.0.

snip_20151105233800

This creates a project with the correct functional cross-section to target .NET Core.

Some time ago I refactored the CSLA codebase so all the actual code files are in a shared project named Csla.Shared. We then have a concrete project for each target platform we support (Xamarin Android and iOS, iOS Classic, .NET 4, 4.5, 4.6, WinRT, UWP, etc.).

snip_20151105234241

This new PCL project is named Csla.NetCore5.0 and it just references that pre-existing shared project to get the same code as every other version of CSLA.

snip_20151105234409

As I mentioned earlier, this bare-bones class library project doesn’t bring in any more of .NET than absolutely necessary. As a result I had to add some NuGet packages required by CSLA.

snip_20151105234659

Or via project.json:

{
  "supports": {
    "net46.app": {},
    "dnxcore50.app": {}
  },
  "dependencies": {
    "Microsoft.NETCore": "5.0.0",
    "Microsoft.NETCore.Portable.Compatibility": "1.0.0",
    "System.Runtime.Serialization.Primitives": "4.0.10",
    "System.Runtime.Serialization.Xml": "4.0.10",
    "System.Threading.ThreadPool" : "4.0.10-beta-23409"
  },
  "frameworks": {
    "dotnet": {
      "imports": "portable-net452"
    }
  }
}

This brings in the BCL functionality required by CSLA.

The one exception is that I didn’t bring in WCF. Instead what I’ve done at the moment is to use a NETCORE compiler directive symbol to exclude the data portal WCF channel from building as part of CSLA for .NET Core. The reason for this is that I had a conversation with one of the Microsoft engineers responsible for this, and it turns out that referencing WCF has a cascade effect where a very large percentage of .NET gets brought into scope (to support WCF).

If your app doesn’t use the WCF data portal channel you shouldn’t have to include all that extraneous code/assemblies in your app. So rather than including the WCF data portal support into core CSLA my plan is to follow the lead of .NET Core itself and break the WCF data portal channel into its own separate assembly (Create .NET Core WCF data portal channel assembly).

There’s one other issue I had to deal with, and that is that in my UWP implementation I used some WinRT APIs – and those aren’t available in “pure” .NET Core. The most notable of these is code in CSLA that captures and restores the current culture and UI culture values on the current thread. Some of this is extremely old code that used to pull the information off the current thread, and then along came WinRT that required a different approach. It turns out that in .NET 4 Microsoft introduced a new API to consolidate the old and new styles of interacting with the culture values. For example, you can now do this:

request.ClientCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
request.ClientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;

The code here works on all platforms, no need to use the current thread in .NET and some WinRT API elsewhere. Very nice!

The one catch is that setting the culture isn’t universally supported in a single model because older versions of .NET (like 4) still require the use of the Thread object. So setting the culture requires a compiler directive.

#if NETFX_CORE
        _clientCulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
        _clientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
#else
        _clientCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
        _clientUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
#endif

And that’s it – pretty easy really – thanks to having added Silverlight support years ago, followed by WinRT support, then UWP support. All the groundwork was laid for pure .NET Core support.

(and it helped that I was doing this work in Redmond so I had direct access to Microsoft engineers that are creating .NET Core Smile )

Just at the moment this work is available in a branch of my fork: https://github.com/rockfordlhotka/csla/tree/337-NetCoreSupport

Once I’ve done some more testing I’ll merge this into the actual CSLA master branch at: https://github.com/MarimerLLC/csla/tree/master

Friday, 06 November 2015 02:11:37 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, 26 October 2015

csla win8_fullMany people look at CSLA .NET and see a big, complex framework. And to be honest, this is an enterprise-grade framework that supports a lot of features, so it can be complex.

But it doesn't have to be, not for the simple scenarios.

So here's a basic walkthrough of creating a Web API service that sits on top of a CSLA business layer.

Remember: This exact same business layer can be reused (unchanged) to support everything from an iOS/Android mobile interface to a web interface to an old-fashioned Windows Forms interface. That is the power of CSLA .NET!

I should point out that even this code isn’t as simple as it could be – but I want to show a proper basic architecture that abstracts the interface, business, and data layers of the application. As a result you’ll end up seeing a number of projects created:

  1. Web API interface
  2. Business library
  3. Abstract data access layer
  4. Concrete data access layer

At the end of this process you’ll have a simple Web API service running. But even better, the projects/assemblies in number 2-4 are 100% reusable across other platforms.

You can get the finished code from GitHub.

1

To start, open Visual Studio 2015 and create an ASP.NET Web Application. I named mine SimpleService.

In the next dialog, indicate that you want to create a Web API style project.

snip_20151026135801

Using NuGet, add a reference to the CSLA-ASPNET-MVC5 package.

snip_20151026140340

2

Next, add a .NET 4.6 Class Library project to the solution. I named mine BusinessLibrary.

Using NuGet, add a reference to the CSLA-Core package.

snip_20151026140457

Also add a reference to the standard System.ComponentModel.DataAnnotations assembly. Thanks to CSLA .NET, the basic validation rules in this assembly not only work with ASP.NET, but also with every other UI technology, even on platforms where this assembly wouldn’t normally be available (like Windows Forms).

3

Now add a simple business class to the business library project. Add a class named PersonEdit.

CSLA supports editable and read-only objects, so I tend to name my classes XyzEdit and XyzInfo to differentiate easily between the type that supports changing data, and the type that typically shows a small subset of data when the user needs to see a list of data.

Edit the class to look like this:

using System;
using System.ComponentModel.DataAnnotations;
using Csla;
 
namespace BusinessLibrary
{
   [Serializable]
   public class PersonEdit : BusinessBase<PersonEdit>
   {
   } }

In the class add a read-only property and a read-write property as follows:

public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
public int Id
{
   get { return GetProperty(IdProperty); }
   private set { SetProperty(IdProperty, value); } } public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(c => c.Name); public string Name {
   get { return GetProperty(NameProperty); }
   set { SetProperty(NameProperty, value); } }

CSLA does include code snippets you can add to your project via the CSLA-Templates NuGet package. Here I’ve used the cslapropg and cslaprop snippets.

Finally, make the Name property required:

[Required]
public string Name
{
   get { return GetProperty(NameProperty); }
   set { SetProperty(NameProperty, value); } }

Note: CSLA .NET has a very powerful rule engine in addition to support of DataAnnotations attributes. The rules engine supports multi-property and multi-object validation, as well as authorization, and data manipulation/calculation. Basically, everything you need to implement virtually any business rule or process can be accommodated by the rule engine.

At this point the business domain class exists. But the only way to create an instance of an object is via the new keyword, and that’s problematic. You should generally use factory methods or dependency injection to create object instances. CSLA supports either, but the easiest approach is to use a factory method. Add the following method to the PersonEdit class.

At this point return to the Web API project and add a reference to the BusinessLibrary project.

    public static async Task<PersonEdit> GetPersonEditAsync(int id)
    {
       return await DataPortal.FetchAsync<PersonEdit>(id);
    }
#if !NETFX_CORE
    public static PersonEdit GetPersonEdit(int id)
    {
       return DataPortal.Fetch<PersonEdit>(id);
    } #endif

You will also need to add a using statement.

using System.Threading.Tasks;

The DataPortal is a CSLA concept that abstracts away creating, retrieving, updating, and deleting business domain objects so you can easily switch between different platforms (Xamarin, .NET, UWP, etc.) and also easily switch between 1-, 2-, 3-, and n-tier physical deployments of your application.

4

Now that the business domain class exists, let’s hook it up to a data access layer.

Add a .NET 4.6 class library to the solution. I named mine Dal.

This project will not contain the data access code, but will contain the definitions for all data operations, basically using a repository pattern. Inside this project I am not creating or using business domain types, I am creating and using data entity types. So where the business domain type created in the previous step is shaped to meet the needs of the interface (in this case the REST API), the types created in this Dal project will be primarily shaped to meet the needs of the database.

Add a data transfer type for person data to the project – a class named PersonDto.

namespace Dal
{
   public class PersonDto
   {
     public int Id { get; set; }
     public string Name { get; set; }
   } }

Add an interface named IPersonDal to the project.

namespace Dal
{
   public interface IPersonDal
   {
     PersonDto GetPerson(int id);
   } }

In a real application your interface would contain other methods as well that might allow other retrieval options, as well as the ability to insert, update, and delete a person data entity.

Next add a .NET 4.6 class library project to the solution named DalMock. This project will contain a concrete implementation of the data access layer we just defined.

Add a project reference from the DalMock project to the Dal project.

In this project add a class named PersonDal.

using Dal;
 
namespace DalMock
{
   public class PersonDal : Dal.IPersonDal
   {
     public PersonDto GetPerson(int id)
     {
       return new PersonDto { Id = id, Name = "Maria Kowalski" };
     }
   } }

Because this is a mock data access layer, it will just return hard-coded test values. You can also create another concrete data access layer project that uses EF or any other data access technology that you prefer.

Finally, the Dal project needs to provide an abstract/dynamic way to load the concrete data access layer assembly. Go back to the Dal project and add a class named DalFactory.

using System;
 
namespace Dal
{
   public static class DalFactory
   {
     public static T GetDal<T>()
     {
       Type dalType = null;
       if (typeof(T) == typeof(IPersonDal))
         dalType = Type.GetType("DalMock.PersonDal, DalMock");
       if (dalType != null)
         return (T)Activator.CreateInstance(dalType);
       else
         throw new Exception("DAL type not found");     }   } }

In a real application you would not hard-code the PersonDal type; instead you would load that type from a configuration file or through some other means. Or perhaps you’d use a full-blown DI container instead of this simple dynamic factory scheme. For this simple demo however, this code illustrates the concept behind dynamically loading a concrete DAL type.

At this point the data access layer itself is complete, so all that remains is to wire up the business domain class to the abstract DAL.

Go to the business library project and add a project reference to the Dal project.

snip_20151026144802

This provides the business domain classes access to the abstract concepts around the data access layer, without providing any access to a concrete DAL implementation.

In the PersonEdit class add the following method.

private void DataPortal_Fetch(int id)
{
   var dal = Dal.DalFactory.GetDal<Dal.IPersonDal>();
   var dto = dal.GetPerson(id);
   using (BypassPropertyChecks)
   {
     Id = dto.Id;
     Name = dto.Name;
   } }

This code interacts with the abstract DAL types in the Dal project, but ultimately invokes the concrete DAL implementation to get back data that is used to load the domain object with the values it needs to do its job.

Now all that remains is to create the REST interface.

5

Return to the SimpleService project and add project references to the Dal and DalMock projects. While the Web API project doesn’t technically need those references, it is critical that those DLLs end up deployed to the bin folder on the web server, and adding these references will cause Visual Studio to handle that detail on our behalf.

With that done, add a Contracts folder to the project. In that folder add a PersonContract class to the project.

namespace SimpleService.Contracts
{
   public class PersonContract
   {
     public int Id { get; set; }
     public string Name { get; set; }
   } }

This class defines the public contract for our API. You should never directly expose your internal business types to the outside world through a service; it is important to keep clean separation between the public interface and your internal implementation.

Next add a Person Web API controller to the project.

snip_20151026142818

using System.Web.Http;
 
namespace SimpleService.Controllers
{
   public class PersonController : ApiController
   {
     // GET: api/Person/5
     public Contracts.PersonContract Get(int id)
     {
       var person = BusinessLibrary.PersonEdit.GetPersonEdit(id);
       return new Contracts.PersonContract
       {
         Id = person.Id,
         Name = person.Name
       };
     }
   } }

This controller uses the factory method of the business domain object to retrieve the requested instance of the domain type. The data from that domain object is loaded into the public API contract type, which is then returned to the caller of the service.

Using this approach you have complete separation and maintainability over what the consumer of the service sees, how the internal business domain model works, and how the data access layer interacts with the database.

If the business layer implements business rules, such as authorization, at a per-property or per-type level, this service implementation would succeed or fail to return those values as it attempted to pull them from the business object. No rules are implemented in the Web API project, because it is part of the interface layer. All rules are implemented in the business layer.

You should now be able to run the Web API project and navigate to the service URL (the port number may vary).

http://localhost:59560/api/Person/5

The result should be JSON that looks like this.

{"Id":5,"Name":"Maria Kowalski"}

For more information about CSLA to go www.cslanet.com.

Monday, 26 October 2015 14:31:08 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, 22 October 2015

LSPK51I’ll be speaking at Live! 360 Orlando, November 16-20. Surrounded by your fellow industry professionals, Live! 360 provides you with immediately usable training and education that will keep you relevant in the workforce.

SPECIAL OFFER: As a speaker, I can extend $600 savings on the 5-day package. Register here: http://bit.ly/LSPK51Home

All roads lead to Live! 360: the ultimate education destination! Bring the issues that keep you up at night and prepare to leave this event with the answers, guidance and training you need.  Register now: http://bit.ly/LSPK51_Reg

Thursday, 22 October 2015 10:55:41 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, 21 September 2015

Universal-Windows-Platform-SmallI recently made an interesting discovery about Universal Windows Platform apps.

When you build and run them in Release mode they are compiled using the .NET Native compiler, and they stop using mscorlib.

Most of your common .NET types come out of mscorlib. For example:

System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=7ce85d7bea7798e

When you are running UWP code in Debug mode that remains true. But in Release mode the use of mscorlib is replaced by System.Private.CoreLib. For example:

System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

In the vast majority of cases nobody cares about the assembly qualified name of a type – unless you are using reflection, in which case you may easily make this same discovery.

In my case, working on CSLA .NET, this difference posed a real challenge. One of the key features of CSLA is the concept of mobile objects, where object graphs transparently flow (move) across the tiers of your application (between AppDomains, processes, or computers over the network). For this to work, the type names of the objects must be the same in the source and destination environments, whether that be an Android client talking to a full .NET server, or a UWP client talking to that same server.

Fortunately ever since ~2007 and Silverlight’s restrictions on reflection (and the fact that it didn’t support BinaryFormatter or NetDataContractSerializer) CSLA has had its own serializer: MobileFormatter.

MobileFormatter has some serious advantages over BinaryFormatter and the NDCS, most notably it works across all platforms in a consistent manner, as well as minimizing the use of reflection and providing substantial control over the format of the byte stream transferred over the network.

In this scenario that last point is important, because I was easily able to enhance MobileFormatter to translate any assembly qualified type name that uses mscorlib or System.Private.CoreLib so the assembly name is an arbitrary text code. I chose /n. The full assembly name becomes /n during serialization, and that code becomes the full assembly name during deserialization.

The result is that types flow between UWP and all other platforms (.NET, Xamarin, etc.) transparently - as always. As a bonus this change reduces the number of bytes transferred over the wire because the full assembly name isn't in the byte stream, just this short code.

I found that benefit to be compelling enough that while I was changing MobileFormatter to solve the mscorlib issue I also added code to translate the CSLA assembly name to /c in the same manner.

In the future I may look at ways to translate user-created assembly names (your business assemblies) into short codes as well, as that would save a lot of bytes on the wire.

Monday, 21 September 2015 15:47:28 (Central Standard Time, UTC-06:00)  #    Disclaimer
On this page....
Search
Archives
Feed your aggregator (RSS 2.0)
November, 2017 (2)
October, 2017 (1)
September, 2017 (3)
August, 2017 (1)
July, 2017 (1)
June, 2017 (1)
May, 2017 (1)
April, 2017 (2)
March, 2017 (1)
February, 2017 (2)
January, 2017 (2)
December, 2016 (5)
November, 2016 (2)
August, 2016 (4)
July, 2016 (2)
June, 2016 (4)
May, 2016 (3)
April, 2016 (4)
March, 2016 (1)
February, 2016 (7)
January, 2016 (4)
December, 2015 (4)
November, 2015 (2)
October, 2015 (2)
September, 2015 (3)
August, 2015 (3)
July, 2015 (2)
June, 2015 (2)
May, 2015 (1)
February, 2015 (1)
January, 2015 (1)
October, 2014 (1)
August, 2014 (2)
July, 2014 (3)
June, 2014 (4)
May, 2014 (2)
April, 2014 (6)
March, 2014 (4)
February, 2014 (4)
January, 2014 (2)
December, 2013 (3)
October, 2013 (3)
August, 2013 (5)
July, 2013 (2)
May, 2013 (3)
April, 2013 (2)
March, 2013 (3)
February, 2013 (7)
January, 2013 (4)
December, 2012 (3)
November, 2012 (3)
October, 2012 (7)
September, 2012 (1)
August, 2012 (4)
July, 2012 (3)
June, 2012 (5)
May, 2012 (4)
April, 2012 (6)
March, 2012 (10)
February, 2012 (2)
January, 2012 (2)
December, 2011 (4)
November, 2011 (6)
October, 2011 (14)
September, 2011 (5)
August, 2011 (3)
June, 2011 (2)
May, 2011 (1)
April, 2011 (3)
March, 2011 (6)
February, 2011 (3)
January, 2011 (6)
December, 2010 (3)
November, 2010 (8)
October, 2010 (6)
September, 2010 (6)
August, 2010 (7)
July, 2010 (8)
June, 2010 (6)
May, 2010 (8)
April, 2010 (13)
March, 2010 (7)
February, 2010 (5)
January, 2010 (9)
December, 2009 (6)
November, 2009 (8)
October, 2009 (11)
September, 2009 (5)
August, 2009 (5)
July, 2009 (10)
June, 2009 (5)
May, 2009 (7)
April, 2009 (7)
March, 2009 (11)
February, 2009 (6)
January, 2009 (9)
December, 2008 (5)
November, 2008 (4)
October, 2008 (7)
September, 2008 (8)
August, 2008 (11)
July, 2008 (11)
June, 2008 (10)
May, 2008 (6)
April, 2008 (8)
March, 2008 (9)
February, 2008 (6)
January, 2008 (6)
December, 2007 (6)
November, 2007 (9)
October, 2007 (7)
September, 2007 (5)
August, 2007 (8)
July, 2007 (6)
June, 2007 (8)
May, 2007 (7)
April, 2007 (9)
March, 2007 (8)
February, 2007 (5)
January, 2007 (9)
December, 2006 (4)
November, 2006 (3)
October, 2006 (4)
September, 2006 (9)
August, 2006 (4)
July, 2006 (9)
June, 2006 (4)
May, 2006 (10)
April, 2006 (4)
March, 2006 (11)
February, 2006 (3)
January, 2006 (13)
December, 2005 (6)
November, 2005 (7)
October, 2005 (4)
September, 2005 (9)
August, 2005 (6)
July, 2005 (7)
June, 2005 (5)
May, 2005 (4)
April, 2005 (7)
March, 2005 (16)
February, 2005 (17)
January, 2005 (17)
December, 2004 (13)
November, 2004 (7)
October, 2004 (14)
September, 2004 (11)
August, 2004 (7)
July, 2004 (3)
June, 2004 (6)
May, 2004 (3)
April, 2004 (2)
March, 2004 (1)
February, 2004 (5)
Categories
About

Powered by: newtelligence dasBlog 2.0.7226.0

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2017, Marimer LLC

Send mail to the author(s) E-mail



Sign In