tag:blogger.com,1999:blog-54167784191367166682024-02-07T19:04:16.490-08:00LUKE PUPLETTMy information super high horse.Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.comBlogger76125tag:blogger.com,1999:blog-5416778419136716668.post-89037763268325238902015-02-27T04:17:00.001-08:002015-02-27T04:17:58.898-08:00Note to Self: Raw dump of all my old Azure notesThis is just a dump from some OneNote pages I took over that last few years. It's completely unstructured and here for my own use, and for anyone else that might find some value in it.<br />
<br />
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Azure Services</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Big data: Hadoop</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Database: SQL Azure</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Storage: Tables, Blobs,
Files, DocumentDB</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Traffic: Traffic Manager,
Networking</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Caching: Redis, AppFabric</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Messaging: Service Bus,
Queues</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Identity: AD, ?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Media: Media Services and
streaming</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Hosting: CDN, Websites, Cloud
Service Worker Roles, WebJobs</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">WebJobs</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Background
processing in Azure Websites</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Deployed <span style="font-style: italic;">with</span> Azure Websites.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Starts with an Console
Application.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Install NuGet:
Microsoft.Azure.WebJobs</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Depends on Azure Storage, so
brings in dependencies.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Add connection strings to
storage and dashboard, use two storage accounts.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Need to setup the accounts in
Azure portal, empty is fine.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
static void
Main()</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
var jobHost = new JobHost();</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
jobHost.RunAndBlock();</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public static
void HelloWorld([QueueTrigger("helloworld")] string message,</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
[Blob("hello/world.txt")]
out string outMessage, TextWriter log)</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// When someone puts a message on queue.</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
string result = "The message is " +
message;</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
log.WriteLine(result);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
outMessage = result;</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
}</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">You can run this locally.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Setup the queue.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">New queue,
"helloworld"</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Added a new message via
context menu on queue in Azure Management Studio.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Hit F5 and Job host starts
and runs the block.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Peeks and triggers and pulls
and sends into the HelloWorld method, no queue-reading code is needed!</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">That's it.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Running in Azure</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">"Always On" needs a
paid website.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Console Application, right
click it, Publish as WebJob…</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Continuously, Scheduled,
Demand.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Continuously is for queue
trigger.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Create a new website, or
attach it to existing.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Only a WebJob is hosted if
new site.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can also add a WebJob as a
zip file via portal.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can use other languages, like
a PowerShell script.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">With C# we can use
diagnostics, logging etc.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
In the olden days</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">We used a CloudService, a
worker role. Still can.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">A cloud service is a way to
package up applications for Azure, in Roles.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Inherits from RoleEntryPoint,
needs OnStart, Run, OnStop, lots of manual coding for reading config file
settings, connecting to cloud storage account, queue account, creating it
if not exist, also connecting to blob storage, container, etc.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Running in a perpetual loop
with own sleep/delay logic.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Azure Caching</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">VM with manually installed
cache like Couchbase.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">New! In the store, there's
Add-ons, Memcachier: New > Store > Memcachier, select plan, failover
etc.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Install NuGet package, Enyim
Memcached.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Redis Cache Solutions for
Azure: available as a service, has grouping and cached lists addressable
via own item index, pub/sub messaging, batch transactions, </span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Redis Service has tiers for
throughput and failover, 250MB-53GB, master-slave basic option for
replication + auto-failover, scale size up instantly. For dev, use
smallest cache that has IOPS limit.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can use it from anywhere, is
public.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Portal: New > Redis Cache</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Azure Automation - Runbooks</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">VM with manually installed
cache like Couchbase.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure Automation is a service
on Azure, a hosted run space, backed by PowerShell Workflow.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">System Center Orchestrator is
very similar.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Centralized Store: values,
credentials, PS modules.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">API for Management coming.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Reporting and history.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Automation accounts are tied
to regions.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Might want to split accounts
for security/access to production credentials.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Assets stored items are
shared across the account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Runbook: a set of scripts to
execute, becomes a 'job'.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Schedules: daily, hourly,
once.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Priced on job run time and
number of runbooks, per account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">For a call to be made to a
HTTPS service (external), need to download and install the certificate
since there is not access to a root cert store.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">By default you get the PS
module for Azure.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Assets: click import module
and browse to a zip file containing the modules.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can now pass a PSCredential
object to authenticate with Azure AD using an "organizational
account".</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can edit the runbook within
the portal on the Author 'tab'.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
workflow
Show-SimpleExample</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
$adminCred = Get-AutomationPSCredential -Name
"NameOfCred"</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
Add-AzureAccount -Credential $adminCred</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
Select-AzureSubscription -SubscriptionName
"MSDN Subscription"</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
Get-AzureService | select servicename</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
}</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Add-AzureAccount is what's
used to authenticate, must be stored statically in the PS
runspace/runscope/process.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Game Services</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Membership, Leaderboards,
Achievements, Downloadable Content, Game Statistics, Game Presence,
Cheating & Banning, Multi-Player Game Stats.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Tricky to choose the right
services, especially as they're changing all the time and getting new
capabilities.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Telemetry, Inquiries,
Commands, Notifications</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Uses Service Bus pub/sub
topics to get telemetry into worker roles for processing.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Uses Relay Service to get
notifications to other drivers (presumably hosting WCF in game) but says
that it's not actually very scalable, use something else.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Storage, uses tables for lap
times and telemetry, blobs for binary lap replay.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Uses ASP.NET MVC website(s)
for lap time display, telemetry API for inquiries and website itself.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">PartitionKey, partitions have
SLA, and order by RowKey</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Telemetry: sending per
sector, once per 10 seconds, sampling data 100ms and batching to send
1/second (interpolation on receive to smooth jumps).</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Halo Game Backend Services</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Service Bus and a worker
process to digest statistics, user stats.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Authentication, XBox sits on
secure network tunneling over the internet.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Security gateways, XBox
secure Protocol, UDP based, have to use SG to talk to public internet.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">"Title
infrastructure"</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">XBox has limited local
storage slots and RAM, need to offload temp data, partial statistics.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">The keep session state and
sessions marked as complete, so crashed servers can resume session state
reload.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Massive scale testing, Azure
Service Bus team had to ask Halo team to stop!</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Scale testing had to be
seriously invested in, no standard tools, record, mutate and playback.
Record the real traffic. Hard to fake generate certain data types.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Like a server side version of
fiddler.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use scheduled service bus
messages, dump millions of messages but scheduled for delivery.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Building Big: Lessons Learned from Customers</span></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">James Hamilton, lessons
learned from building Windows Live, </span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Partitioning your
application.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Optimising for density.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Caching</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Millions of users, 200,000++
ops per second, 1000s of cores, 100s of databases.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Redundancy and Fault Recovery</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Commodity hardware slice.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Single version software.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Multi-tenancy.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Support geo-distribution.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Automatic provisioning and
installation.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Configuration and code as a
unit.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Manage roles, not servers.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Deal with multi-system
failures.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Recover at the service level.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Stateless is the goal.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Small code optimizations can
have massive impact on your cloud bill.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Typical Workloads</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Content Delivery: websites
and services, session state, transient state, shopping cart.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Content Exploration: Per-user
content view, per user-stateful progress, doesn't touch other user data,
fairly simple to scale.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Social Graph and Content:
comments, likes, global reach between users, loosely consistent, async
updates to n customers, I must see my comment immediately but its okay for
it to take a short time for others to see it.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Interactive Gaming: n user
content view, game actions, session, global reach, state updates shared to
n players.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Capacity, adding for demand,
partitioning scheme.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Optimize, resource usage,
efficiency</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Shift, trade durability,
queryability, consistency for throughput, latency.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Play to strengths of
components available.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure compute, fairly easy to
scale up and out</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure storage, 100TB,
5000iops per partition, 3Gbps, normally hit iops limit first, more
partitions or more accounts.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure SQL Database, 150GB,
305 threads, 400 concurrent reqs, hard to partition because the query
semantic doesn't account for partitions/cost of operation.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Horizontal partitioning,
shards, split by rows, needs balanced part key.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Vertical partitioning, split
by columns, can be done across storage types easily on the cloud.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Hybrid, shard + dimension
data on other storage mediums.</span></li>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="circle">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Select part value, Last
Name, must consider field that won't change.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Convert to part key, like
hash it, speed vs. collisions vs. distro, mod by bucket count</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Map key to logical
partition.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Map logical partition to
physical partition.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">End up with a connection
string.</span></li>
</ul>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .75in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Range Based, ranges adjusted
to even out the parts.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Logical Buckets, assign to
logical bucket and assign to physical store, can have more than one
logical per physical.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Lookup assignment, lookup
table to physical resource.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Twitter, two tiers of people,
normal people with 300 followers, celebrities.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Querying over shards, gather
and query, query is done in data tier.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Eventual consistency can be
done, geo scale with local write that the writer customer can see, then
background task write elsewhere, or pop on queue.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Submit queries to all nodes
manually, gather results.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">SQL Azure Federations, does
sharding for you and live splits, works for some problems, the central
gateway becomes the choke point.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Consider rush hour in a
region, consider using region in quiet region.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Caching</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Memcached clients are aware
of servers and keys.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Windows Azure cache knows
Azure, cache is deployed as a worker role.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Partitioning is driven by
server, has high avail option and perf monitor counters.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can add instances, auto
handles it, but cannot remove easily.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Dual write so reliable with
small overhead. Does your app care, need cache hits?</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Part 2</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">The importance of designing
for insight, instrumentation, performance and reliability.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Design for failure, part of
the system being offline, ignore or queue, retry, backlog.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Putting trace or logging
config in a config file won't work in the cloud, need to design a remote
config system.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">There is a good chance of
long periods, minutes, or downtimes per month, and be within SLA.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Deal with it.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">More components, more chance
of something being down.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Hiccups, retry a few times,
then mark as down.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Node down, service down,
entire region hit by act of God.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">CloudFX library, has retry
policy, then throws a transient.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">RETRIES MUST HAVE RANDOM
DELAY</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Retries should be coordinated
with other retires stacking up, only one call retrying and the others
either queuing or failing completely without even trying.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Semaphore around the retry
resource, object.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Load needs to be spread over
regions.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Route away from failures.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Press Association deployed to
8 datacentres.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Traffic Manager has route
poor performance, get closest DC by IP, but routed when bad.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Location is not the same as
IP latency, use IP latency.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Traffic Manager has custom
health probing in SDK.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Queues duped in different
regions, processors local, sucking from local and dupe queues.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">How quickly should I react to
new insight?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Do I know the question or am
I exploring data?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">KPI, time series, scalar
stat, trending, ratios.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">How much data is required to
gain insight?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Perf stats against app stats,
like total users, active users.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">How much of the source signal
do I need for insight?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Local computation vs. global
system computation?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Requests queued is your most
important metric.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">New Relic works on Azure by
agent.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">OpsTera</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">PagerDuty</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">WAD Windows Azure Diagnostics</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">WAD has challenges, won't
give 3rd party diag, perf data is written to table storage with 60 time
based partition key, and so IOPS is bottlenecked when monitoring many
servers, have to turn down the sampling.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Queue based means alerts can
be slow to propagate.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Stores are not very
queryable, table store!</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Table Store</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Stores performance counter
and application log data.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">General max through is 1000
entities per partition per table per account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Same cap on the out.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Split data by history and
realtime, push to a logging service that splits.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">High value: filter,
aggregate, publish to anything written is actionable; alerts, dashboards,
operational intelligence.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">High volume: batch,
partition, archive; trends, root cause, mining.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">WAD is very configurable;
verbose written to file and then forwarded to blob storage. Blob storage
can sustain this sort of load up to 1000 instances per storage account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Keep storage accounts
separate for instrumentation data.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Create a custom data source
in WAD, monitoring a folder, if I put the file here, you put the file
there.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Log4Net: Rolling files is all
you need, do all async writes.</span></li>
</ul>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// logging and
retry with CloudFX</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
try</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
Stopwatch stopWatch = null;</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
if (TimeMethods && !String.IsNullOrEmpty(methodName))</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
stopWatch = Stopwatch.StartNew();</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
using (var connection = new ReliableSqlConnection(connectionString,
_policy))</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
using (DbPolicyObserver reporter =
ConfigureDaPolicyObserver(methodName))</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: 1.125in; margin: 0in;">
connection.Open();</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: 1.125in; margin: 0in;">
ret = func(connection);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
if (stopWatch != null)</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
stopWatch.Stop();</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .75in; margin: 0in;">
Logger.TraceApi(String.Format("{0}.{1}", ComponentName,
methodName), stopWatch.Elapsed);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
} </div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
catch(Exception
e)</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
{</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
Logger.Warning(e, "Error in...");</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
throw;</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
}</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Best Practices on MS SQL Server on Azure Virtual
Machines</span></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Affinity Groups, under
settings; group resources as objects that work together, Azure provisions
them to work together.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Availability Sets ensure
resources do not get shut down together (updates, outages per rack).</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Virtual Network; vNet and
subnets and DNS servers, your playground, can have same addressing space
because they're separate. Hard to change later/impossible.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can link to premises via perm
VPN via hardware, or can put replicated AD or new AD and trust, can also
point-site via Windows client.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can set AD server as DNS
server for your vLan, though VMs must be DHCP assigned by Azure, though
lease is like infinite.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can configure network infra
in Azure via XML files.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Don't put TempDB on local
Azure disk anymore, Azure practices change fast.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Deployment/Licensing</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">SQL Server Gallery Images
have licensing implications; for Windows Server, your license is inclusive
of time up. For MSSQL, this is the same.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">License mobility lets you
move on-prem license to Azure, so use a vanilla Windows gallery image and
load on.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can upload a VHD, even use
SysPrep.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Backup to cloud (from
on-prem):</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
CREATE CREDENTIAL
myCred</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
WITH</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
IDENTITY
= 'TechEd-Creds',</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
SECRET='<storagekey>'</storagekey></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
BACKUP DATABASE
[ReportingServerScale]</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
TO</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
URL
= '<a href="http://x.blobl.core.windows.net/sql/blah.bak">http://x.blobl.core.windows.net/sql/blah.bak</a>'</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
WITH</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
CREDENTIAL
= 'myCredential',</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
NOFORMAT,</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
NOINIT,</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
NAME
= N'TechEd Demo',</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
SKIP,</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
NOREWIND,</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
NOUNLOAD,</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
STATS
= 10</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
GO</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Recommendation for
MSSQL on VM</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Remove unused endpoints on
the VM.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use virtual networks instead
of public RDP ports to administer your VMs.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use VPN tunnel to connect to
database servers.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Carefully plan virtual
networks to avoid re-configuration; have to tear down and rebuild
everything if the network needs resizing.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use Availability Sets and
Affinity Groups with VMs.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use mixed mode authentication
when not in a domain; Windows mode is default but not always best idea.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Add new port endpoint and add
load balancing to it via the portal.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Not sure if balancer is aware
of downed node.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Make sure Windows Update
times are staggered to avoid downtime, even if in same Availability Group.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Enable database connection
encryption, not default.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Run ALTER SERVICE MASTER KEY
REGENERATE because gallery uses same image.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Service Bus</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Note: Azure Queues
part of Azure Storage services, also exist and are more feature limited.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<a href="http://msdn.microsoft.com/en-us/library/azure/hh767287.aspx">http://msdn.microsoft.com/en-us/library/azure/hh767287.aspx</a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Queues, part of Azure
Messaging services.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Topics, pub/sub event
aggregator</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Relays</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Notifications</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">With Azure queues, if the
content of the message is not XML-safe, then it must be Base64 encoded. If
you Base64-encode the message, the user payload can be up to 48 KB,
instead of 64 KB.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Each message is comprised of
a header and a body. Cannot exceed 256 KB.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Max concurrent TCP
connections to a single queue 100 shared between senders and receivers,
limit not imposed using REST.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Queue size between 1 and 80
GB.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure queues and Service Bus
queues: 2,000 msg/s with 1KB.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Azure queues: 10ms latency
with no nagling.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">SB queues: 20-25ms.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">For decoupling, load
leveling, scale out.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Topics allow for:</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Broadcast and partition</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Content based routing</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Messaging Patterns</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
SDK 1.8</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Message Lock Renewal, for
slow processing.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Entity queries, in C# and
REST, see code example below.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Forward Messages between
entities, trees of queues composed together for supporting 1000s topics,
topic forwards to 100 topics, each forwards to 100 etc.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Batch APIs</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Browse sessions</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Updating entities,
enable/disable</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">ConnectionString config file
key based setup supported.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Notification Hub
Preview</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Scalable, cross platform,
push notification.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
SDK 2.0 </div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Shared Access Secrets (SAS
key), namespace and entity level, via C# or Azure portal, regen/revoke
keys.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Auto-delete Idle Entities,
clean up idle topic, idle sub clients auto clean, good for auto scale down
cleaning up subs not used, or test debris.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Event-Driven Model, to remove
hardship of writing correct receive loop, now SDK can have observers for
receive, exception.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Tasked-based Async API</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Browsing Messages</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
SDK 2.1</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">AMQP, JP Morgan standardised
messaging protocol.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Paired Namespaces</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// How to set
SAS rule on an entity</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
QueueDescription
qd = new QueueDescription(qPath);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
sendRule = new <span style="background: yellow; mso-highlight: yellow;">SharedAccessAuthorizationRule</span>(</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
"ruleName",</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
SharedAccessAuthorizationRule.GenerateRandomKey(),</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
new [] { AccessRights.Send });</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
qd.Authorization.Add(sendRule);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
namespaceManager.CreateQueue(qd);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// How to
connect to a queue using SAS</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
Uri runtimeUri
= ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace,
string.Empty);</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
MessagingFactory
mf = MessagingFactory.Create(</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
runtimeUri,</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
TokenProvider.<span style="background: yellow; mso-highlight: yellow;">CreateSharedAccessSignatureTokenProvider</span>(keyName,
key));</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
QueueClient
sendClient = mf.CreateQueueClient(qPath);</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Max 12 rules per entity.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Before this, needed to use
"Users" or AD federation.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// Entity Query
API</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
IEnumerable<queuedescription>
queueList = nameSpaceManager</queuedescription></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
.GetQueues("messageCount Gt 10");</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
IEnumerable<topicdescription>
topicList = nameSpaceManager</topicdescription></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
.GetTopics("startswith(path, 'foo') eq true AND AccessedAt Lt
'" + startTime + "'");</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
IEnumerable<subscriptiondescription>
subscriptionList = nameSpaceManager</subscriptiondescription></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
.GetSubscriptions(topicName, "messageCount Gt 0 AND AccessedAt Lt
'" + startTime + "'");</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<a href="http://%3Cservicebusaddress%3E/$Resources/Topics?$filter=startsWith(path">http://<servicebusaddress>/$Resources/Topics?$filter=startsWith(path</servicebusaddress></a>,
'foo/bar') eq true</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// Looks like
OData, so can use Linq?</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">For querying when you have
many queues, topics etc.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use case: filter for unused
queues.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// Message
Browse - peeking</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
QueueClient
queueClient = QueueClient.Create("myQ");</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
queueClient..Peek();
// does not lock the message.</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
queueClient.Peek(fromSequenceNumber:
4); // specific starting point.</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
queueClient.PeekBatch(messageCount:
10); // supports batching.</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
// Asynchronous
API</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
queueClient.SendAsync(currentOrder);</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
AMQP</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Efficient, binary.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Reliable, fire forget,
exactly once delivery</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Portable data reppresentation</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Flexible, client-client,
client-broker, broker-broker</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Broker-model independent</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 24.0pt; margin: 0in;">
<span style="font-weight: bold;">Table Storage</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin-left: .375in; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">See also Blobs, Drives, Azure
Queues, Files.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Primary and secondary access
keys (also now supports direct REST access)</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Data items called 'entities'</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Fixed PartitionKey, RowKey
and Timestamp properties</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">252 additional properties of
any name, schemaless.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">PK and RK form clustered
index.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">AtomPub REST and .NET APIs</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
[DataServiceKey("PartitionKey",
"RowKey")]</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public class Movie {</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
/// Movie Category is the partition key
public string PartitionKey { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
/// Movie Title is the row key public
string RowKey { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public DateTime Timestamp { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public int ReleaseYear { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public double Rating { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public string Language { get; set; }</div>
<div style="font-family: "Courier New"; font-size: 9.0pt; margin: 0in;">
public bool Favorite { get; set; }</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">.NET uses the concept of a
context and changes are made to the context and saved, can thus be
batched/transaction. Similar entity change tracking to EF.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Null values are ignored by
storage engine.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Queries are begun using
context.CreateQuery and look like EF Linq queries.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Scanning a part or range of parts done using
.CompareTo("Key") >= 0</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
where
fooEntity.PartitionKey == partionKey</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
&&
fooEntity.RowKey.CompareTo(lowerBoundRowKey) >= 0</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
&&
fooEntity.RowKey.CompareTo(upperBoundRowKey) <= 0</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
where </div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
fooEntity.PartitionKey.CompareTo(lowerBoundPartKey) >= 0</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
&&
fooEntity.PartitionKey.CompareTo(upperBoundPartKey) <= 0</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Tips</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Use a new context for each
op, context object is not thread safe.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Can use
IgnoreResourceNotFoundException and use null return to avoid exception
overhead on empty lookup 404.</span></li>
</ul>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Performance</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<br />
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Scans depend on row size, not
just rows in partition, rows in where set.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Research whether best to run
a single query spanning range of parts, vs. running concurrent queries on
each part?</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Partitions served from single
server.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Avoid hot partitions,
unbalanced schemes.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">See "Lessons
Learned" above for tips on shard key mapping algos.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">Row size: 1MB</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">200TB per table</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">1,000 rows per query
response, use continuation token, no snapshot consistency.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">500TB per storage account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">20,000 entities or
messages/second per account.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">10Gbit/s in 20 out for geo
redundant, 20 in 30 out for local redundant.</span></li>
<li style="margin-bottom: 0; margin-top: 0; vertical-align: middle;"><span style="font-family: Calibri; font-size: 11.0pt;">2,000 entities/second per
partition.</span></li>
</ul>
Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-75417813627588943492013-07-09T04:19:00.001-07:002013-07-09T04:19:51.906-07:00Note to Self: The Windows Store GridView Control, Deconstructed<p>Here’s a diagram of the GridView control for Windows Store apps, deconstructed into its components. This is intended to show all the templates and styles in various places to help customise this complex control.</p> <p><img src="http://farm6.staticflickr.com/5530/9247893752_5596019a67_b.jpg" width="608" height="288" /></p> <p>Download <a href="http://farm6.staticflickr.com/5530/9247893752_5596019a67_b_d.jpg">here</a>.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-12898198709185837732013-04-22T01:42:00.001-07:002013-04-22T01:42:00.221-07:00Converting ASP.NET WebForms to ASP.NET MVC 4.0<p>This is a blog-in-progress while I try to convert an ASP.NET WebForms application to MVC 4. It may completely fail or I may give up, but I thought it might help to share my experiences.</p> <p><strong>What I am Migrating</strong></p> <p>It’s a one project ASP.NET WebForms 3.5 site. It’s pretty simple, uses the old Ext JavaScript framework, which became Sencha UI, I think. There’s a fair few pages but not a lot of HTML in each, since its built in XSLT (vomit) from XML coming from an XML database. Much business logic is in the data-layer (vomit II).</p> <p><strong>Strategy</strong></p> <p>My bright idea is not to convert. I don’t think that’s the easiest route, I just don’t know what’s needed for an MVC app, and I want the IDE to be in MVC mode, with the context menu support for views and stuff, which probably won’t happen if I just add some DLL references and setup some routing.</p> <p>So, I will make a new, empty MVC 4 app and copy in the files from the old world. I know MVC is happy to serve-up ASPX forms pages and controls, and that’s all a WebForms site is – just some ASPX pages and some handlers, maybe some URL rewriting.</p> <p><strong>Start</strong></p> <p>So far, I have:</p> <ul> <li>Created an empty, new ASP.NET MVC 4.0 project.</li> <li>Set the same project references and NuGet packages.</li> <li>Set my solution and project configurations for staging/QA.</li> <li>Copied over all the stuff from the old Web.config that I think are non-standard, i.e. added to support the old app. I already did this, so its hard to blog at detail but its actually pretty simple.</li> <li>Begun to copy over the basic, high-in-the-dependency-graph controls and pages.</li> </ul> <p><strong>Copying Stuff Across</strong></p> <p>I have copied /MasterPages and its children, /Classes which are just some .cs files with helpers inside, /Controls which are Web User Controls or ASCX files as well as the default.aspx (all come with their code-behind and designer).</p> <p><strong>Problem 1 – Solved</strong></p> <p>In copying the files, drag and drop, from the WebForms project in the same solution, the IDs of the controls on the ‘pages’ (in the ASPX or ASCX files) are not being ‘seen’ in the code-behind. By that, I mean there are red squigglies in the C# wherever they are referenced – its like the controls on the pages are not being compiled.</p> <p>I reconstructed a control manually, by adding a new one with a different name and copying over the important mark-up and code. This was fine, so MVC is cool with it, just doesn’t like it being copied file by file.</p> <p>So I figured that it must be related to the designer file. The file doesn’t sit at the same level in the Solution Explorer as the manually created good one, so there’s something odd going on. Opening the designer.cs file is fine but the code doesn’t respond to mouse-overs – its lifeless like a text file.</p> <p><strong>Solution: </strong>The trick is to delete the file and then right-click its parent AS?X file and hit <strong>Convert to Web Application</strong> which forces regeneration of the designer.cs.</p> <p>You can copy a load in and then convert at the folder or project level, too, donchaknow.</p> <p><strong>Problem 2 – Solved</strong></p> <p>The default route and getting default.aspx to be the page shown at the domain root. This one is easy, although I’m not sure its the proper way. Simple add this route.</p> <p>routes.MapPageRoute("HomePage", "", "~/default.aspx");</p> <p><strong>Problem 3 – Solved</strong></p> <p>Settings in httpHandlers not working, i.e. still going via the routing system. So this site has a load of magic setup in the web.config to make friendly-URLs happen. Of course, this needs to be re-considered in an MVC world, but we’re talking about things like blah.xml which invokes a special handler – its all custom stuff for this old site.</p> <p>The solution was two step:</p> <p>- Add the following line to not route requests:</p> <p>routes.IgnoreRoute("{resource}.xml");</p> <p>- Also need to update the types in the httpHandlers section in web.config</p> <p><add verb="*" path="*.xml" type="Company.XmlHandler, SiteDllFile" /></p> <p>- To</p> <p><add verb="*" path="*.xml" type="Company.XmlHandler, NewMvcSiteDllFile" /></p> <p><strong>Problem 4</strong></p> <p>The form values security and validation seems to have been tightened-up in ASP.NET 4.0 or something, because I was getting an exception when reading Form values containing XML fragments. This was remedied with this config setting:</p> <p><httpRuntime requestValidationMode="2.0"/></p> <p><strong>Problem 5 – At this stage, there has been no problem 4</strong></p> <p>With everything else copied over and some shared components refactored out into a shared library, everything else is working.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com2tag:blogger.com,1999:blog-5416778419136716668.post-53727124979263616182013-04-15T04:32:00.001-07:002013-04-15T04:32:50.955-07:00Data says Git is officially the world's most woeful piece of softwareWhen computer programmers have a problem, they turn to StackOverflow. The site has a great feature to vote-up a question, so rather than ask the same question, you can say "Me too" by casting a vote.<br />
<br />
So what then is the software with the highest voted questions?<br />
<br />
Overwhelmingly, Git.<br />
<br />
<br />
<div class="MsoPlainText">
<a href="http://stackoverflow.com/questions?sort=votes&pagesize=50">http://stackoverflow.com/questions?sort=votes&pagesize=50</a><o:p></o:p></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
Problems with Git are responsible for 1 in 5 of the top-voted questions on StackOverflow, which is really saying something when it is such a small tool compared to say, an entire language.</div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
So next time you're having problems with Git and someone tells you its not Git's fault, don't blame the tool, you can point out that it actually really is the most woeful programming software in existence today.</div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
There's a lot of hate for Git but it also has a very active and noisy tribe of supporters, that get very defensive when people dare to criticize Git. Of course, the problem is that criticism and confronting problems is the first step towards making improvements, which banishes Git to an ugly status quo.</div>
Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com3tag:blogger.com,1999:blog-5416778419136716668.post-55521075848176358472013-01-22T03:35:00.000-08:002013-01-22T04:01:24.067-08:00Ensuring that two PowerShell scripts don't run at the same timeThis quick PowerShell snippet shows how you can ensure only one instance of a script or section of a script executes at a time on a system, i.e. a server running scheduled tasks.<br />
<br />
The script will wait while the other script or section completes. The Dispose method releases the mutex and allows any other scripts to take it and run. It should ideally be in a finally block to ensure it always gets released, although I've read that it uses a .NET critical finalizer to ensure release but I don't know if this works as well in PowerShell as it would in a proper .NET process.<br />
<br />
<pre> [System.Threading.Mutex]$mutant;
try
{
# Obtain a system mutex that prevents more than one deployment taking place at the same time.
[bool]$wasCreated = $false;
$mutant = New-Object System.Threading.Mutex($true, "MyMutex", [ref] $wasCreated);
if (!$wasCreated)
{ </pre>
<pre> $mutant.WaitOne();
}
### Do Work ###
}
finally
{ </pre>
<pre> $mutant.ReleaseMutex();
$mutant.Dispose();
}
</pre>
Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com7tag:blogger.com,1999:blog-5416778419136716668.post-70447115238705930102012-12-13T07:39:00.000-08:002012-12-13T07:40:28.234-08:00Remote PowerShell like SSH<p>Here's a super quick howto for using PowerShell like you Linux dudes use SSH to remotely console into a server.</p>
<p>First, make sure Windows Remote Management is setup on the target server. So RDP onto the box and open a command prompt. Run this:</p>
<p>
<code>winrm quickconfig</code>
</p>
<p>Now that's setup, close RDP and on your client admin dev type box, open PowerShell 2.0</p>
<p>Run the following commands.</p>
<code>
$domainAdmin = Get-Credential
<br/>
# Enter your domain admin or other privileged credentials in the box that pops up.
<br/>
Enter-PSSession -ComputerName web3-pool2-ln -Credential $domainAdmin
</code>
<p>After a few seconds the prompt should change and you're in. Use 'exit' to come out.</p>Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com2Rotherfield, East Sussex, UK51.046062 0.219450.9661995 0.061471500000000012 51.125924499999996 0.3773285tag:blogger.com,1999:blog-5416778419136716668.post-14427711499347374202012-05-18T06:56:00.001-07:002012-05-23T05:46:10.409-07:00Facebook Login for Windows Phone Apps<strong>The brief: allow new customers to sign up and sign in with their Facebook account, because they have this option on the website, so they’re going to need it in the phone app.</strong><br />
<strong>This is a high-level blog post about enabling Facebook login in a Windows Phone application. Once you’ve configured your app at and got your client/consumer ID and secret from developers.facebook.com, the process to actually authenticate your users is very simple - it’s the bigger picture that’s more difficult and so this blog post aims to prepare you rather than give you a few code snippets for what is essentially just extracting some tokens from a string.</strong><br />
So, with that said, these are the things to consider before writing any code:<br />
<ul>
<li>How does OAuth work? </li>
<li>How will a Facebook account map to my accounts? </li>
<li>How does this affect my current secure authentication? </li>
<li>How will the login screen work on the phone? </li>
<li>What happens when the app has been slept for a long time? </li>
</ul>
<h3>
How does OAuth work</h3>
Facebook uses a version of OAuth. Personally, I like learning specifications and writing my own code, rather than learning a framework or SDK. Usually, the spec is more clearly documented than other people’s SDKs. <br />
Facebook has its own documentation covering how to authenticate, which I strongly advise you to read. The OAuth specification will give you a wider understanding, it’s pretty simple, but I must point out that Facebook doesn’t stick to the spec. <br />
I’m going to explain the process in a nutshell here, but before I do that, consider that your application must register with Facebook and obtain a Consumer ID and Secret which will identify your app to Facebook. The aim is to get hold of an Access Token, which is a short-lived ticket that represents your rights to act on behalf of a Facebook customer. <br />
<ul>
<li>There are a few types of authentication, depending on whether you’re building web apps or mobile/desktop/GUI apps. </li>
<li><strong>For a web app</strong>, your server redirects the user to the Facebook OAuth sign-in page and passes across your Consumer ID so Facebook knows it’s issuing an Access Token for your app. </li>
<li>When doing so, you pass Facebook a URL to redirect back to, after the user signs in. </li>
<li>Your server ‘waits’ for the redirect and then extracts a temporary token from the redirect which it used to fetch the proper Access Token directly from Facebook, using an HTTP get. </li>
<li><strong>For a client app</strong> with a UI, it’s much simpler. </li>
<li>Place a Web Browser control on a page and hook-up the Navigated event. </li>
<li>You automate the Web Browser control to navigate to the Facebook OAuth sign-in page, the user then logs in. </li>
<li>Facebook then redirects to a page you specify (at a domain you preconfigure with Facebook) and in the URL’s fragment portion, is the Access Token, as this occurs, the Navigated event fires a few times. </li>
<li>Inspect the Uri at each point to see if it has the Access Token or an error code. As soon as you have the token, you can progress the UI to the next stage. </li>
<li>You’re looking for access_token=xyz and expires_in=123 (seconds) parameters in the Fragment portion of the URI, it’s simply a case of parsing the string.</li>
</ul>
<h3>
Why use Facebook to authenticate your customers?</h3>
Essentially, there are only a couple of reasons. The first is integration: you’d like your app to connect to Facebook and programmatically post to your customer’s feed or see who their friends are, perhaps. The second is to reduce sign-up friction and provide a better experience to the on-boarding process. This may be simply to remove the need for a customer to remember another password (and providing a way to reset forgotten passwords) or because your sign-up process asks a bunch of questions that you could actually just pull from their Facebook profile. <br />
In the latter case, you’ll likely have your own customer entities in a database that will need to be linked to a Facebook account. <br />
<h3>
Mapping the Facebook account to your own accounts</h3>
If you’re retrofitting Facebook login to an existing app, then you’ve probably already got your own login process, so you’re going to need to offer a login screen supporting the old username and password sign-in as well as the new OAuth method.<br />
As mentioned above, you might need to have a process for reading some details from Facebook and creating an account entity in your own system, and you may even wish to offer a way for users of the old sign-in scheme to connect their accounts.<br />
I won’t go into detail about how to do this linkage, but whichever way you choose to accomplish it, you’ll need to ensure that another Facebook OAuth application cannot simply log-in to your app by just sending a Facebook ID to your login system.<br />
Your server-side system should require the Access Token and user’s Facebook ID, and then use the Access Token against the Facebook Graph API directly to obtain the default FB account and check the ID for the user it returns matches what you’ve been sent.<br />
You’ll also need to prove that the Access Token and user ID have come from your app, so you’ll need to sign the data with a secret that’s shared between your servers and your app, which means obtaining/agreeing a key before the Facebook sign-up occurs.<br />
If you don’t do this, then there’s nothing to stop another Facebook app from getting an Access Token and FB user ID and sending them to your login endpoint and masquerading as one of your customers!<br />
There’s an inherent weakness here, in my opinion, that could be strengthened if, when your server fetches the user account using the supplied Access Token from Facebook, you supply your App Secret and FB could ensure that the Access Token was issued to your app.<br />
<h3>
How will the login screen work on the phone?</h3>
If you don’t have an existing login scheme then you only need to supply the Facebook login option, unless for privacy reasons, you’d like to allow your customers to sign-up without Facebook.<br />
It’s safe to assume that login will take place from a dedicated page, as opposed to a popup control. The user should only be bothered by the login screen when they need to login, and that page needs to play host to a web browser.<br />
We also need to consider sign-up, as well as sign-in; your application may need to collect extra information on sign-up, data that’s not available from Facebook, but also, your customers might not want to use Facebook.<br />
In my scenario, I have a dedicated page and flow for non-Facebook sign-up, and a dedicated page and flow for Facebook sign-up and sign-in (combined).<br />
The flow goes something like this:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM2eOaQvb65fqpYp4CNJhCakqgl9MplTj_2Itvwxbok9nF_xcFqia-_iu5rar2olKFYYgewosMU58lyfn3e5A-3grGXuhZa_gEjKUIGdNYkRAIjeRso0L7QwQJvrHJ6c0MA1njUnYyYLvQ/s1600-h/OAuth%252520Page%252520Flow%25255B3%25255D.png"><img alt="OAuth Page Flow" border="0" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzLcuisOOzgaivMeeS4zqYqoqkMKTShH-HMcPowor6fpP4B6weyLood7by6UazrMpbKcjx7QXGlPYT2EqGLBxpp3VrB3NRALCgnrSKpOEJyT8iitdI-tzSieyqnlGcE58R15fDsJuT8CzR/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="OAuth Page Flow" width="630" /></a><br />
The left-most page is the Home Panorama which detects a guest login and provides two menu options for logging-in and signing-up.<br />
The top path consists of:<br />
<ul>
<li>The Login Method Selector page, offering the Facebook login and a normal username + password UI. </li>
<li>Using the latter will call the normal login web service and follow the quick route back to the Home page, while selecting Facebook login, will navigate to a page with a Web Browser control.</li>
<li>This page will display the standard Facebook OAuth login screen and upon entering details, the browser control will vanish and, if the customer is signing-up, they’ll be presented with a page through which they can supply a screen-name, otherwise, if logging-in, they’re just navigated to the Home page.</li>
<li>If sign-up goes well, then a welcome message is displayed and the user is offered the option to post a Wall message or click to go straight to the Home page.</li>
</ul>
The bottom path consists of:<br />
<ul>
<li>The Sign-up Method Selector page, offering Facebook and ‘Manual’. </li>
<li>The Facebook option takes the user to the top flow, whereas the manual route consists of a few more pages / UI that collects and checks all the extra data that’s needed to create an account, data that is normally taken from their FB account details.</li>
</ul>
<h3>
What happens when the app has been slept for a long time?</h3>
Login credentials are persisted between app use sessions and the Home page is able to detect which login method the user used last time. For a Facebook login, the previous Facebook Access Token is verified and, if expired, the app navigates to the Facebook login page and brings up the Web Browser control.<br />
If the Web Browser has cached login details then the browser will automatically be logged-in, without the user typing anything, and the app will navigate back to the Home page. This flow happens so quickly that it appears that the app opens at the Facebook page, looks busy for a couple of seconds and then goes to the Home page.<br />
This flow might take some time on slow networks but Manual logins can simply authenticate without navigating anywhere and work much more smoothly.<br />
So far, this is all fine and dandy, but in reality the Home page is not the first page of an app. An app may be entered via the back button or on resume, into a state where the user is no longer considered logged-in – the Access Token has expired or your server session has been pruned.<br />
In my app, I use my own MVCVM pattern. I have a Controller in addition to the ViewModel. This is just a personal preference, I like to keep my ViewModels as just ‘binding and commanding surfaces’ with no logic.<br />
Doing things this way keeps me from adding spiralling side-effect logic in property setters and coerces me to use dedicated helper and utility classes rather than be tempted to inherit too much application logic - I’ve worked on apps that reuse logic by VM subclassing and it gets ugly. I also like to build standard ‘dumb’ VMs which can be reused across the app and contain only what needs to be on the screen.<br />
Saying that, I do use inheritance in this situation. My base PageController has a set of virtual methods which orchestrate all the initialization, one of which is called to check authentication. <br />
Each time a page is navigated to, the PageController runs some code to ensure the user is logged-in which allows me to redirect the user to the Login page and return afterwards using the BackStack. I also check the BackStack and remove the sign-in pages so the user can’t back into them.<br />
With this logic on each page, even if the user lets the phone go idle overnight while on a page deep within my app, the Login flow will run in the morning, as soon as the page resumes.<br />
Of course, you don’t have to have funky Controllers and virtuals to do this, but it needs bearing in mind that authentication isn’t just something that happens on the Home screen.<br />
Time will tell whether this page flow method works. It’s perfectly feasible to embed a Web Control in a popup UI control or inject it into the visual tree. As networks get faster (I’m looking at you, 4G), then Facebook login will become a less irksome UI dance.<br />
Have fun, and here’s some useful links:<br />
Facebook Authentication Documentation<br />
<a href="http://developers.facebook.com/docs/authentication/">http://developers.facebook.com/docs/authentication/</a><br />
OAuth 2.12 – although Facebook strays from the standard in some fairly major ways.<br />
<a href="http://tools.ietf.org/pdf/draft-ietf-oauth-v2-12.pdf">http://tools.ietf.org/pdf/draft-ietf-oauth-v2-12.pdf</a><br />
Where Facebook veres from the OAuth standard.<br />
<a href="http://stackoverflow.com/questions/9724442/is-facebooks-oauth-2-0-authentication-a-strict-implementation-of-the-rfc">http://stackoverflow.com/questions/9724442/is-facebooks-oauth-2-0-authentication-a-strict-implementation-of-the-rfc</a>Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com4tag:blogger.com,1999:blog-5416778419136716668.post-70242429553616059042012-05-16T01:52:00.001-07:002012-05-16T01:52:58.934-07:00Windows Phone Panorama background image cropped when smaller than screen size.<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju-U53dBkGakB1_V1XxjHAESYo3IA-1txk8KgAk4HqaQW5YP6Pnb72mPmhfOYO0VmSAZm3iqvnPj4MUuvI3r9OyPK2kv27WKmuL87WaNuxig3gu9QN-kgkjXuaJyCLWqw_xZNtOqayRwoc/s1600-h/Cropped%25255B4%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Cropped" border="0" alt="Cropped" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtHIAtWD1mPe-J103GKxWBQOHhOXczMA_QcSzN5aYf2vCgDbuMUX2x20-cXNNR2J2jbVr9h-kaEqfmd1zFOdRPYOlBoNCCUiw7Ug5z1BPnD5MhW-dZ7KLJPsk5DSaQdHuqzRfPoeQl2edl/?imgmax=800" width="263" height="436" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzT-sc0UVIlqJCd8FC0Hp8O2pRSZXrdiUtGHAoE7ezULTRSg6iO_WB3Xju57w9OqCyJ2hRUNKn8U6s-U2SXzZ3ECd2rqud9zSrwlcFb3oRcLVDJnhcZqUmEpf2PXvlFy2hsar9fWDiGc0g/s1600-h/Perfect%25255B3%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Perfect" border="0" alt="Perfect" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieimSwmjkDQalBCjBFmdgDVr6skeX6Z7PFkUjL_IPJuq6h1epPJzxiCCoV3ohqCXZP7HLVOwGKwhvjL61i9dkyN8zRHSEQDSz7XAn6PuwPXIxfAGIUEET3bSY5-RHQCOOyNrLHHOiOhY3i/?imgmax=800" width="263" height="436" /></a></p> <p>Notice that the background image repeats just before the ‘r’ on the right side of the left image, but its fine on the other image.</p> <p>This image on the left is 512x384 whereas the image on the right is twice the size, 1024x768. It seems that when the image must be stretched to fill the height of the screen, the width is truncated. When an image must be shrunk to fit, then the width is preserved.</p> <p>The Sretch property isn’t required for the larger image, but it works when set as Fill or UniformToFill. The smaller image needs UniformToFill to look correct.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-14963713589920731152012-03-01T08:27:00.001-08:002012-03-01T08:28:16.409-08:00Raw Notes-OData Web Services<p><b>OData</b></p> <p>EF</p> <p>Linq-to-SQL</p> <p>IQueryable<T> (can be collection.AsQueryable() but collection must be the whole set)</p> <p>Custom Provider</p> <p>DataServiceKeyAttribute on entity defines the property that has the unique id.</p> <p>Add WCF Data Service item to project.</p> <p>Gives service class deriving from DataService<T> where T is provider (IQueryable)</p> <p>In InitializeService override, set config options for default security.</p> <p>That’s it. /Actors will correspond to public IQueryable<Actor> Actors member on provider!</p> <p>Filtering and paging etc. will just work via URL.</p> <p>An OData service is a RESTful WCF service so it supports custom operations, like any other service operation, and can use WebGet and WebInvoke for GET, PUT, POST, DELETE</p> <p><b>Adding a new resource:</b></p> <p>// in ServiceOData : DataService<T> class <br />[WebGet] <br />public IQueryable<Person> TopPeople() <br />{ <br />return (from p in CurrentDataSource.people <br />let rating = p.reviews.Average(r => r.rating) <br />where rating > 9 <br />orderby rating <br />select p).Take(20); <br />}</p> <p>Then provide access via </p> <p>config.SetServiceOperationAccessRule(“TopPeople”, ServiceOperationRights.All);</p> <p>Method/operation parameters passed in by URL query string.</p> <p><b>Filters and Interceptors</b></p> <p>Query interceptors apply to GET operations and do business rule validation, security, further filtering. E.g. only return records for the customer.</p> <p>Change interceptors apply to POST, PUT, DELETE and do security, rejection, blasphemy.</p> <p>Implement both with operations on the data service class using attributes, or by entity in general.</p> <p>[QueryInterceptor(“people”)] <br />public Expression<Func<person, bool>> FilterPeople() <br />{ <br />return (p) => p.department == “IT”; <br />}</p> <p>[ChangeInterceptor(“people”)] <br />public void FilterPersonChange(person r, UpdateOperations ops) <br />{ <br />if (ops == UpdateOperations.Add && (p.Name == “Dave CEO”)) <br />throw new DataServiceException(400, “No-one updates the boss.”); <br />}</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-17599684379205862872012-02-29T11:52:00.001-08:002012-02-29T11:52:23.869-08:00Raw Notes–WCF 4.0 New Features<p><b>WCF 4.0 Notes</b></p> <p>Default Endpoints</p> <p>Base addreses + contracts (HTTP, TCP)</p> <p>WCF creates endpoints based on info it has, above.</p> <p>Default Bindings - binding with no name becomes default.</p> <p>Default Behaviours – behaviour with no name becomes the default.</p> <p>Standard Endpoints – built-in endpoints in common configurations.</p> <p>File-less Activcation – Config file defines what is usually in the .svc file, but your service is still /blah.svc</p> <p><b>REST</b></p> <p>HTTP Cache now works.</p> <p>Message Format selection is now done with HTTP headers as it should be.</p> <p>WebFaultException now automatically does HTTP codes and everything.</p> <p>ASP.NET routes means you can remove .svc file.</p> <p><b>Service Discovery</b></p> <p>Ad-hoc mode is broadcast based, enquire and announce to local subnet.</p> <p>Managed mode is a central proxy/catalog.</p> <p><b>Message Routing</b></p> <p>Rules-based and transport neutral so HTTP can go via MSMQ.</p> <p>Server in DMZ and routed to inside.</p> <p>Bridge protocols (e.g. HTTP > net.tcp)</p> <p>Well-known public façade for many services.</p> <p>Load balancing, routes can be round-robin or fallback on timeout.</p> <p>Failover.</p> <p>Multicast one-way message to receivers that need to know.</p> <p><b>WCF 4.0 Config Model Updates</b></p> <p><b>Default Endpoints</b></p> <p>One per contract/base address combination. This is done via protocolMapping, which can be tweaked.</p> <p>If any endpoints are configured, then this overrides the auto config. So adding a MEX endpoint in code will screw it up, so you need to call host.AddDefaultEndpoints();</p> <p><b>Default Bindings & Behaviours</b></p> <p>So you can now setup defaults in machine.config and override in web.config.</p> <p>Common behaviours are not new to 4.0 but these allow additive behaviours and are only allowed in machine.config <commonBehaviors></p> <p><b>Standard Endpoints</b></p> <p>Use the kind attribute on the endpoint, mexEndpoint, discoveryEndpoint, webHttpEndpoint for REST.</p> <p><endpoint kind=”webHttpEndpoint”> ßfails because it needs contract</p> <p><endpoint kind=”webHttpEndpoint” contract=”lala”></p> <p><endpoint kind=”mexEndpoint” address=”/mex”> ß needs address</p> <p>No other configuration needed.</p> <p><b>WCF 4.0 REST Updates</b></p> <p>Automatic Help page shows available verbs and actions, <webHttp> helpEnabled=”true” and visit blah.svc/help</p> <p>Caching works like this:</p> <p>[AspNetCacheProfile(“CacheFor10Seconds”)] <br />[WebGet(UriTemplate=XmlItemTemplate)] <br />[OperationContract] <br />public ...</p> <p>Profiles are added like this (aspNetCompatibilityEnabled=”true” must be set):</p> <p><system.web> <br /><outputCacheSettings> <br /><outputCacheProfiles> <br /><add name=”CacheFor10Seconds” duration=”10” varyByHeader=”Accept” varyByParam=”” /></p> <p>Message Format Selection</p> <p>Needs switching on:</p> <p><system.serviceModel/standardEndpoints/webHttpEndpoint/standardEndpoint name=”” automaticFormatSelectionEnabled=”true” /></p> <p><b>WCF Routes</b></p> <p>// Global.asax called from Application_Start <br />private void RegisterRoutes() <br />{ <br />var f = new WebServiceHostFactory(); <br />RouteTable.Routes.Add(new ServiceRoute(“Data”, factory, typeof(MyService))); <br />}</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-41810187949088644042012-02-29T11:50:00.001-08:002012-02-29T11:50:22.336-08:00Raw Notes: Facebook for Devs<p><b>Raw notes, unedited.</b></p> <p><b>Facebook</b></p> <p>Community</p> <p>Conversations</p> <p>Curate Identities</p> <p>Social Graph – Model of users and objects and interactions.</p> <p>Social Channels – Mechanisms apps to reach users. News feeds. App requests. Bookmarks.</p> <p>Social Plugins – Facebook UI directly exposed in app.</p> <p>Graph API & FQL – Authenticate and grant (OAuth?) and then app can interact.</p> <p>Pages and Page Tabs – tabs are iframes, often hosting Page Tab Apps. These are the good looking pages you see, like Coke.</p> <p>Canvas App – App inside Facebook site chrome.</p> <p><b>Social Graph</b></p> <p>Mike -> Likes -> Page <br />Mike -> Plays -> Game <br />Mike -> Checked-into -> Thing <br />Mike -> Friends -> Dave <br />Dave -> Likes -> Page</p> <p>Apps can access the social graph.</p> <p><b>Facebook Apps</b></p> <p>Create an app, like Twitter.</p> <p>Apps are hosted on your own infrastructure, code runs on your box.</p> <p>Authentication using Facebook is OAuth.</p> <p>Canvas Apps get a POST to callback URL with parameter with JSON of the user account.</p> <p>App namespace is the bit after the facebook.com/yournamespace</p> <p>Your URLs are just the root (base) and can have stuff after, like <b>mydomain.com/fb</b>/somethingelse/blah/2</p> <p><b>Social Plugins</b></p> <p>Like Button</p> <p>Login – login to site and authenticate on your site via Facebook.</p> <p>Registration – similar to above.</p> <p>Activity Feed and Recommendations – Friends and Pages that their friends have interacted with on your website.</p> <p>Like Box – Include on site a button to allow a user to Like your Facebook page.</p> <p>Facepile – Faces of user’s friends that have already liked the site.</p> <p>Live Stream – Webcast interaction, comments.</p> <p>Send button – Send link to page to Facebook friends.</p> <p>Page needs meta properties – <a href="http://ogp.me/ns#">http://ogp.me/ns#</a></p> <p>E.g. <meta property=”og:title” content=”My Social Plugins” /></p> <p>Facebook Insights works with fb:app_id or fog:app_id (look it up) meta tag.</p> <p>Need to us FB JavaScript SDK.</p> <p><b>Dialogs</b></p> <p>Feed – Post to timeline from within app/site.</p> <p>Send – Send message to friends using FB messaging.</p> <p>Requests – Send request to friends from any site, but brings them back to Canvas app.</p> <p><b>Graph API</b></p> <p>graph.facebook.com REST API</p> <p>Objects have unique IDs as string, so GET graph.facebook.com/id would fetch it, as would /?ids=id1,id2</p> <p>Some objects have an id that is a URL itself, GET graph.facebook.com/?ids=http://blah.com</p> <p>?fields=id,name,location can limited or expand fields returned, since=unixtime&until=unixtime</p> <p>?metadata=1 gives list of object fields and object connections, which can be used to drill down.</p> <p>?limit=3 takes the top n results.</p> <p>?offset=100&limit=50 is paging control.</p> <p>Can batch API calls in one call. See FB docs.</p> <p>Realtime Updates also available.</p> <p><b>Creating Objects</b></p> <p>Create an object by adding it to a collection, using the object id and connection that represents the collection you’re adding to, e.g. POST to /me/events with event parameters where events is the connection (collection).</p> <p>Graph Explorer at developers.facebook.com is awesome tool for understanding formats, security and possibilities.</p> <p>FQL gives SELECT as in /fql?q=SELECT name FROM user WHERE uid = 16416123</p> <p><b>Dates</b></p> <p>Dates returned in ISO-8601</p> <p>Can specify date_format</p> <p>date_format=U for Unix <br />date_format=r for Thu, 17 Nov 2011 18:00:16 +0000</p> <p>Graph API default timezone is UTC, but FQL is PST (UTC-8)</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-73189380456673230492012-02-28T06:01:00.001-08:002012-02-28T06:02:32.493-08:00On Corporates, Recruitment Agencies and CVs<div class="MsoNormal"></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><b>Word Format</b></span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">I don’t know about you, but I seem to remember that a digital format for a cross-platform, virtual hard-copy of a document which pretty-much guarantees the integrity of the original was invented in 1993. I believe it to have been popular, too, possibly adopted by most of humanity, and that this technology goes by the name of Portable Document Format, or PDF.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">So why, after elegantly crafting and kerning my CV to look and feel tip-top, do I have to disseminate it in the format of one particular writing tool and, in doing so, lose control over its look, feel, and more importantly, what I wrote and thus my professional identity?</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">For me, a CV needs to arrive unfettered by anyone other than the person that wrote it. To do otherwise is to do a massive disservice to the recruitment process.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">If a candidate feels they would gain from having their CV titivated by someone else, then so be it, that’s between them, but under no circumstances should anyone touch my intellectual property without my consent, even if they think it is in my best interests.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">A CV works both ways. It’s a filtration system that works for the author as well as the reader. When you go out on a date, the best policy is to be yourself. The reason is simple: masquerading as a different person might mean you end up on a second date, or even in a relationship, but someday soon you’re going to have to drop the act and upset everyone.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Companies need different types of people and personalities, just like good muesli needs fruit, oats and some whole nuts. A CV can communicate fruit, nut or that powdery filler stuff, very well. Your CV not appealing to a person looking for a particular skillset or personality isn’t necessarily a bad outcome.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">If a creative, flamboyant person puts a CV together in Notepad.exe, then they’re misrepresenting themselves. They may appeal to the hiring manager, bowled over by the simple clean layout and monotonic palette, and land up with a job at the Institute of Writing Boring Policy, but they’ll be surfing the Internet job boards again before you can say cornflakes.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Agencies that have a standard format for all their candidates are the very worst perpetrators of this obstruction of justice.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Your CV shouldn’t have to appeal to the hiring manager. If you think demonstrating that you can layout information or that you can string sentences together and not choose 19 different fonts in the process is important for the job, then do it. If the recruiter then tells you that they want to just see a list of acronyms, then find out if this is because they’re new to the job and following process or whether it’s actually coming from the people hiring, and then run very fast.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Often recruiters are just telling you what their clients are saying. But sometimes they’re not. Remember that recruiters don’t do the job, and this inhibits their ability to know what their client wants to see. They’re not creative types, they not copywriters, they not designer-developers, they don’t read your industry magazine; they’re sales people.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">I’m a computer programmer working in an age where the boundaries between jobs are blurring. People are increasingly straddling creative aspects, a sea-change that has been driven by tooling which, in turn, has been driven by higher expectations and an increasing care about software usability and design. Corporates are waking up to the fact that sexy software doesn’t have to be expensive, its more efficient and can even impact staff retention.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Meanwhile, I’m going to continue to write my CV in a way that best reflects my abilities, and secures it from meddling middle-men in the process.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><b>Not reading the CVs.</b></span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">In my industry, IT, there tends to be a general antipathy towards reading a person’s CV. The inclination not to bother putting in the requisite, and I must say polite, effort to reading these highly important documents, is prevalent throughout the entire hiring pipeline.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">My dictionary says that a company is “a number of individuals assembled or associated together; group of people”. The sum total of a company is its people. So any prospective new member of that group is a potentially highly important asset that deserves some time to evaluate.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">It seems that big business hasn’t got this time to give. They certainly have no time to invest in recruiting directly, so they pay head-hunting companies a not-insignificant fee to do it for them. The interesting thing is that these companies don’t actually read the CVs either. It turns out that they receive too many to read properly, which is understandable given that they’ve exposed themselves directly to the firehose, but surely, they should read those that they’ve short-listed, I mean, it’s their main job right?</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">But it’s not the recruitment consultants that worry me. Why isn’t the hiring manager at Big Corp. reading your CV? Why didn’t your boss read your CV?</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">It’s no surprise that most corporate intraware is, well, not quite the standard you get from the wacky company that’s renowned for its weird interview process, or the little shop in Brighton for that matter.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">The whole approach of big business to hiring seems to be about getting the inconvenience of it all, out of the way, as quickly as possible. And it is quite inconvenient. For me, the reason it feels like a waste of my afternoon is because no official time is given to it and no allowances made in deadlines; it’s something we must fit-in just before heading out to reception to meet erm, whatsherface, did you print me a copy of her CV?</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Outside of large corporations, in start-ups and the more boutique businesses, niche players and small producers of high-quality products and services - services that are often sold back to the big corporates - take a different approach to hiring. They often do it directly through recommendations or communities and networks, or using LinkedIn themselves, and they do it slowly, all year round, because good people, like good fortune, can’t just be dialed up on the phone.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Small businesses know all too well how important recruitment is because each person represents a significantly higher percentage of their total brain-stock. It’s only when the company reaches a critical mass does the impact of a person become less obvious and they no longer remember how important it was, and then standards drop as the old ‘inefficient’ hiring practices are streamlined, outsourced and then hidden and erased only to spring up an hour before the interview. Surprise!</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">The new standards with their urgency and importance appear to turnaround hiring much faster and ‘waste’ less time, time that could be spent on vital production matters. Then, because the smart people are too busy working on the smart new product, an average person is put in charge of hiring and then it’s definitely all over.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Mediocrity replicates fast and comprehensively, like bacteria. There may be a number of reasons for this, but here’s a few I’ve seen, both as insidious as each other.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">1 – Mediocre people think interviewing is going all Alan Sugar on their wimpy little asses.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">I can only blame The Apprentice, but since the show has been running, I’ve noticed a distinct rise in hostility and bravado coming across the table in interviews more akin to gang initiations than any assessment of ability and experience.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Not only does this stem from blunt-instrument employees being given hiring authority without appropriate training but also seems to be common in industries that massively over estimate how stressful their working environment is and how resilient candidates need to be. The, see if he can handle a good kicking for this trade-floor job, approach. I’ve work on trade-floors and they’re about as scary as a pub at a cricket match.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">2 - Talent so bright is scares the hiring manager.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Once a person that’s not brilliant is in a supervisory position they become scared of being found out, an anxiety that is often relative to their pay. Protectionism is rife in well-paid, blue-chip corporate structures.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">I once heard that brilliant teams can’t remember where a good idea came from. Talented people are comfortable in their skins and relish being in a fertile band of great people. They illuminate each other. The seek each other out.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">3 - It takes one to know one.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Beyond ticking boxes and matching skills and acronyms like a dating algorithm, talent takes spotting, and that needs like-minded people. It is said that a rotten apple spoils the whole barrel, but they don’t have to be rotten: averageness likes to be all-pervading, too.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Talent can be subtle in its guises. By definition, the best people are different, but the differences are invisible to people operating on the narrow-band spectrum - they can’t see those beguiling new colours.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">In each case, the answer is to have consistently awesome people involved in the hiring process to ensure consistently awesome people get hired, and then devote some proper time and training to it.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Good luck.</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;"><br />
</span></div><div class="MsoNormal"><span style="font-size: 12px; line-height: 13px;">Luke</span></div><div style="font-size: 12px; line-height: 13px;"><br />
</div>Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-5712181081433567702011-10-02T03:43:00.001-07:002011-10-02T03:44:43.804-07:00Solved: black border around screen with HDMI<p><strong>After purchasing 2 Benq HD2420HD for £125 each (!) from Amazon, I got a nasty black border around the image on the HMDI-connected panel.</strong></p> <p>To remove the nasty black border around the screen when a panel is connected via HDMI, set the Overscan to 0%, the menu option for ATI cards can be found here:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmD_rnlgYfJgvXKqpTq-BUq568yOqLBNeQMaEmJ8WCx8dAtWDLuC6ZuRCvo4e7Lf4oG1AMnpZaPaLRu-LAKVHQ-dr2gdxIcDrQ90vEGoPnIPNfo_tfq92Y5v1NRvRcf5itNFchdrCAco8O/s1600-h/image%25255B3%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic41pzJlN_siXpKcb8bvv-MioumqnbJ7pvUuOV1uvOzNKUxh0qanH-xhrKm5AsNpblwIG9F3JDQBK5t8CJANe9fWmgQa05jN2I-CFmV5rbYiHubVZjCaJfsVO3m2qK9R9A2VqFZcSW5efm/?imgmax=800" width="628" height="625" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCuNCZ-F3ogh9WTIputArENIs7rYgh_otmqQHY5YQNJI4uyxfmB7d4bUafSLVJ4OiptuecrVgmA9oRI5cMLvjldx_3DhDRBcU_fO8b1nyZXZDOgYtpBCZ3zwZrUz3EzrTHH3AP4-W70MWR/s1600-h/image%25255B8%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB5DeCsb5RI4dkGVRRsZIhPORUO156JX0bByWLL26jjKTFc1aES7RlBpqZqNC8WV3m-ApWkP5Q-V5Dcsg8Ann2uVIDnpG0yEnGqAPDoX0wW31EJmiuNCx1o5QLN-FZVgTtsAT12buRj8y8/?imgmax=800" width="630" height="617" /></a></p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-76777649389998662662011-09-25T04:40:00.001-07:002011-09-28T01:11:51.306-07:00Combining Anonymous Types with Dynamic<strong>This short blog post shows the outcome of a quick experiment. I am researching a way to back a WPF View with a ViewModel whose properties are not known until runtime.</strong><br />
<strong><br />
</strong><br />
It’s been a long time since I last blogged. I built a house, I’ve had a baby, well, Cassie did the hard work, and also worked on a very large Silverlight project for a large investment bank (a foreign exchange trading platform) and then moved again to a start-up in the West End of London.<br />
<br />
The former job was all hush-hush and even though our small team had the pleasure of a couple of exclusive hours with Silverlight evangelist Mike Taulty, we weren’t able to tell him what we were working on. So blogging was out of the question, which is a real shame for me and the community as a whole, in my opinion (although understandable).<br />
<h5>The Interesting Bit</h5>Anyway, while playing this afternoon, I discovered that anonymous types can escape the confines of the scope they’re declared in by returning them as dynamic!<br />
Check this out:<br />
<div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:30e80d6f-d0c1-40f2-884b-ca97be0e833c" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><pre style="background-color: white; height: 641px; overflow: auto; width: 634px;"><div><span style="color: teal;"> 1</span> <span style="color: black;"> </span><span style="color: blue;">static</span><span style="color: black;"> </span><span style="color: blue;">void</span><span style="color: black;"> Main(</span><span style="color: blue;">string</span><span style="color: black;">[] args)
</span><span style="color: teal;"> 2</span> <span style="color: black;"> {
</span><span style="color: teal;"> 3</span> <span style="color: black;"> var rows </span><span style="color: black;">=</span><span style="color: black;"> ReadDynamicRows();
</span><span style="color: teal;"> 4</span> <span style="color: black;">
</span><span style="color: teal;"> 5</span> <span style="color: black;"> </span><span style="color: blue;">foreach</span><span style="color: black;"> (var row </span><span style="color: blue;">in</span><span style="color: black;"> rows)
</span><span style="color: teal;"> 6</span> <span style="color: black;"> Console.WriteLine(row.Id);
</span><span style="color: teal;"> 7</span> <span style="color: black;">
</span><span style="color: teal;"> 8</span> <span style="color: black;"> </span><span style="color: blue;">object</span><span style="color: black;"> o </span><span style="color: black;">=</span><span style="color: black;"> rows[</span><span style="color: purple;">0</span><span style="color: black;">];
</span><span style="color: teal;"> 9</span> <span style="color: black;"> var properties </span><span style="color: black;">=</span><span style="color: black;"> o.GetType().GetProperties();
</span><span style="color: teal;">10</span> <span style="color: black;"> }
</span><span style="color: teal;">11</span> <span style="color: black;">
</span><span style="color: teal;">12</span> <span style="color: black;"> </span><span style="color: blue;">private</span><span style="color: black;"> </span><span style="color: blue;">static</span><span style="color: black;"> List</span><span style="color: black;"><</span><span style="color: black;">dynamic</span><span style="color: black;">></span><span style="color: black;"> ReadDynamicRows()
</span><span style="color: teal;">13</span> <span style="color: black;"> {
</span><span style="color: teal;">14</span> <span style="color: black;"> dynamic row;
</span><span style="color: teal;">15</span> <span style="color: black;"> List</span><span style="color: black;"><</span><span style="color: black;">dynamic</span><span style="color: black;">></span><span style="color: black;"> rows </span><span style="color: black;">=</span><span style="color: black;"> </span><span style="color: blue;">new</span><span style="color: black;"> List</span><span style="color: black;"><</span><span style="color: black;">dynamic</span><span style="color: black;">></span><span style="color: black;">();
</span><span style="color: teal;">16</span> <span style="color: black;"> </span><span style="color: blue;">using</span><span style="color: black;"> (var reader </span><span style="color: black;">=</span><span style="color: black;">
</span><span style="color: teal;">17</span> <span style="color: black;"> DataHelper.ExecuteSqlStatementReader(
</span><span style="color: teal;">18</span> <span style="color: black;"> DataHelper.BuildConnectionString(),
</span><span style="color: teal;">19</span> <span style="color: black;"> </span><span style="color: maroon;">"</span><span style="color: maroon;">SELECT TOP 1000 * FROM SomeTable</span><span style="color: maroon;">"</span><span style="color: black;">))
</span><span style="color: teal;">20</span> <span style="color: black;"> {
</span><span style="color: teal;">21</span> <span style="color: black;"> </span><span style="color: blue;">while</span><span style="color: black;"> (reader.Read())
</span><span style="color: teal;">22</span> <span style="color: black;"> {
</span><span style="color: teal;">23</span> <span style="color: black;"> row </span><span style="color: black;">=</span><span style="color: black;"> </span><span style="color: blue;">new</span><span style="color: black;">
</span><span style="color: teal;">24</span> <span style="color: black;"> {
</span><span style="color: teal;">25</span> <span style="color: black;"> Id </span><span style="color: black;">=</span><span style="color: black;"> reader.GetString(</span><span style="color: purple;">0</span><span style="color: black;">),
</span><span style="color: teal;">26</span> <span style="color: black;"> };
</span><span style="color: teal;">27</span> <span style="color: black;">
</span><span style="color: teal;">28</span> <span style="color: black;"> rows.Add(row);
</span><span style="color: teal;">29</span> <span style="color: black;"> }
</span><span style="color: teal;">30</span> <span style="color: black;"> }
</span><span style="color: teal;">31</span> <span style="color: black;">
</span><span style="color: teal;">32</span> <span style="color: black;"> </span><span style="color: blue;">return</span><span style="color: black;"> rows;
</span><span style="color: teal;">33</span> <span style="color: black;"> }</span></div></pre></div><br />
<br />
What’s really interesting to me is that the properties can be reflected upon. In my experiments with the dynamic type, this isn’t true and so databinding won’t work.<br />
<br />
<br />
I don’t believe its that simple to stick them in an ObservableCollection bound to a DataGrid because the mechanics of it uses <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.icustomtypedescriptor.aspx">ICustomTypeDescriptor</a><br />
<br />
<br />
More to come... (have a train to catch)Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-47472140590839996942011-01-05T07:17:00.001-08:002011-01-05T07:17:47.977-08:00Note to self: Reading extended file properties<p><strong>To read the extended file property metadata from a file, such as a the exposure of a photo or the duration of some media file, then follow these simple steps.</strong></p> <p>Download and reference the Windows API Code Pack, no link here since it changes name and version, but it easily found in Bing.</p> <p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:9c648241-4628-4f29-9516-0e6046f35c4d" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 435px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000;">//</span><span style="color: #008000;"> Usings</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br /></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System;<br /></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.IO;<br /></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.WindowsAPICodePack.Shell;<br /></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.WindowsAPICodePack.Shell.PropertySystem;<br /><br /></span><span style="color: #008000;">//</span><span style="color: #008000;"> Method</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br /></span><span style="color: #0000FF;">string</span><span style="color: #000000;"> mediaPath </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">@"</span><span style="color: #800000;">c:\Users\Public\Recorded TV\Shark Tale_BBC ONE_2010_12_31_14_08_00.wtv</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /><br />var file </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> FileInfo(mediaPath);<br /><br /></span><span style="color: #008000;">//</span><span style="color: #008000;"> The formatId and propertyId values can be taken from MSDN:<br /></span><span style="color: #008000;">//</span><span style="color: #008000;"> </span><span style="color: #008000; text-decoration: underline;">http://msdn.microsoft.com/en-us/library/bb787399</span><span style="color: #008000;">(v=VS.85).aspx<br /></span><span style="color: #008000;">//<br /></span><span style="color: #000000;">PropertyKey pk </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyKey(</span><span style="color: #800000;">"</span><span style="color: #800000;">64440490-4C8B-11D1-8B70-080036B11A03</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #800080;">3</span><span style="color: #000000;">);<br />var p </span><span style="color: #000000;">=</span><span style="color: #000000;"> ShellFile.FromFilePath(file.FullName).Properties.GetProperty(pk);<br /><br /></span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (p </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)<br />{<br /> Console.WriteLine(</span><span style="color: #0000FF;">string</span><span style="color: #000000;">.Concat(p.CanonicalName, </span><span style="color: #800000;">"</span><span style="color: #800000;">: </span><span style="color: #800000;">"</span><span style="color: #000000;">, p.ValueAsObject));<br /><br /> UInt64 d </span><span style="color: #000000;">=</span><span style="color: #000000;"> (UInt64)p.ValueAsObject;<br /> var duration </span><span style="color: #000000;">=</span><span style="color: #000000;"> TimeSpan.FromTicks((</span><span style="color: #0000FF;">long</span><span style="color: #000000;">)d);<br />}<br /></span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div></p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-66460357895452391362010-12-17T14:08:00.001-08:002010-12-17T14:08:11.741-08:00To PowerShell or Not<p><strong>To pull down, sort out and import the guide data for vuPlan.tv I thought it would be a good excuse to use PowerShell. I’ve been wanting to use this for ages, to get up-to-speed with what the future of scripting on MS Windows looks like.</strong></p> <p><strong>I hated every moment of it.</strong></p> <p>This simple script took more than a whole day to write.</p> <p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:824ad451-181f-433a-8239-9603098b0a54" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 435px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000;">#<br />#</span><span style="color: #008000;"> Looks for the latest downloaded .zip file and extracts its contents.</span><span style="color: #008000;"><br />#<br /></span><span style="color: #000000;"><br /></span><span style="color: #800080;">$random</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object </span><span style="color: #000000;">-</span><span style="color: #000000;">typename System.Random<br /><br /></span><span style="color: #800080;">$dataRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">C:\DATA</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$sourceFolder</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$dataRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">\EPG</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$extractRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$dataRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">\EPG\TEMP-</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$random</span><span style="color: #000000;">.Next(</span><span style="color: #000000;">100</span><span style="color: #000000;">)<br /></span><span style="color: #800080;">$dataRepository</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$dataRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">\EPG\HEAP</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$unzipToolPath</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$dataRoot</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">\unzip.exe</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$importerToolPath</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">C:\Users\Public\Documents\~Main\Vuplan\Evoq.Vuplan.Data.Epg.Importer\Evoq.Vuplan.Data.Epg.Importer\bin\Release\import.exe</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /><br />clear<br /><br />set</span><span style="color: #000000;">-</span><span style="color: #000000;">location </span><span style="color: #800080;">$sourceFolder</span><span style="color: #000000;"><br /></span><span style="color: #008000;">#</span><span style="color: #008000;">$latestFiles = get-childitem | where { $_.Name -like "*TV*" -and $_.LastWriteTime.Date -eq [DateTime]::Now.Date }</span><span style="color: #008000;"><br /></span><span style="color: #800080;">$files</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> get</span><span style="color: #000000;">-</span><span style="color: #000000;">childitem </span><span style="color: #000000;">|</span><span style="color: #000000;"> where { </span><span style="color: #800080;">$_</span><span style="color: #000000;">.PSIsContainer </span><span style="color: #008080;">-eq</span><span style="color: #000000;"> </span><span style="color: #0000FF;">$false</span><span style="color: #000000;"> }<br /></span><span style="color: #800080;">$latestFiles</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$files</span><span style="color: #000000;"> </span><span style="color: #000000;">|</span><span style="color: #000000;"> sort </span><span style="color: #000000;">-</span><span style="color: #000000;">property </span><span style="color: #000000;">@</span><span style="color: #000000;">{Expression</span><span style="color: #000000;">=</span><span style="color: #000000;">{ </span><span style="color: #800080;">$_</span><span style="color: #000000;">.LastWriteTime }; Ascending</span><span style="color: #000000;">=</span><span style="color: #0000FF;">$false</span><span style="color: #000000;">}<br /></span><span style="color: #800080;">$latestZip</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$latestFiles</span><span style="color: #000000;">[</span><span style="color: #000000;">0</span><span style="color: #000000;">]<br />echo </span><span style="color: #800000;">"</span><span style="color: #800000;">Extracting </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$latestZip</span><span style="color: #000000;">.FullName </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;"> to </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$extractRoot</span><span style="color: #000000;"><br />md </span><span style="color: #800080;">$extractRoot</span><span style="color: #000000;"><br /><br /></span><span style="color: #008000;">#</span><span style="color: #008000;"> This little chunk of code unzips using Windows shell but problems with the feckin .zip file mean</span><span style="color: #008000;"><br />#</span><span style="color: #008000;"> that some files extract twice and invoke a UI prompt for overwrite-replace.</span><span style="color: #008000;"><br />#</span><span style="color: #008000;"> </span><span style="color: #008000;"><br />#</span><span style="color: #008000;">$shell = new-object -com shell.application</span><span style="color: #008000;"><br />#</span><span style="color: #008000;">$zipFile = $shell.namespace($latestZip.FullName)</span><span style="color: #008000;"><br />#</span><span style="color: #008000;">$extractTo = $shell.namespace($extractRoot)</span><span style="color: #008000;"><br />#</span><span style="color: #008000;">$extractTo.Copyhere($zipFile.Items())</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br /></span><span style="color: #008000;">#</span><span style="color: #008000;">foreach($item in $extractTo.Items) {</span><span style="color: #008000;"><br />#</span><span style="color: #008000;"> </span><span style="color: #008000;"><br />#</span><span style="color: #008000;"> $item</span><span style="color: #008000;"><br />#</span><span style="color: #008000;">}</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br /></span><span style="color: #800080;">$processArgs</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">-o </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$latestZip</span><span style="color: #000000;">.FullName </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;"> -d </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$extractRoot</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object System.Diagnostics.ProcessStartInfo(</span><span style="color: #800080;">$unzipToolPath</span><span style="color: #000000;">, </span><span style="color: #800080;">$processArgs</span><span style="color: #000000;">)<br /></span><span style="color: #800080;">$startInfo</span><span style="color: #000000;">.UseShellExecute </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">$false</span><span style="color: #000000;"><br /><br /></span><span style="color: #800080;">$unzipProcess</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object System.Diagnostics.</span><span style="color: #0000FF;">Process</span><span style="color: #000000;">;<br /></span><span style="color: #800080;">$unzipProcess</span><span style="color: #000000;">.StartInfo </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"><br />echo </span><span style="color: #800000;">"</span><span style="color: #800000;">Starting process.</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /></span><span style="color: #800080;">$unzipProcess</span><span style="color: #000000;">.Start()<br /><br /></span><span style="color: #0000FF;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #800080;">$unzipProcess</span><span style="color: #000000;">.HasExited)<br />{<br /> echo </span><span style="color: #800000;">"</span><span style="color: #800000;">Waiting for process to complete...</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> [System.Threading.Thread]</span><span style="color: #000000;">::</span><span style="color: #000000;">Sleep(</span><span style="color: #000000;">1000</span><span style="color: #000000;">)<br />}<br /><br /></span><span style="color: #800080;">$sourceDirectoryInfo</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object System.IO.DirectoryInfo(</span><span style="color: #800080;">$extractRoot</span><span style="color: #000000;">)<br /></span><span style="color: #0000FF;">foreach</span><span style="color: #000000;"> (</span><span style="color: #800080;">$item</span><span style="color: #000000;"> </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> </span><span style="color: #800080;">$sourceDirectoryInfo</span><span style="color: #000000;">.GetFiles())<br />{<br /> </span><span style="color: #800080;">$destinationPath</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> [String]</span><span style="color: #000000;">::</span><span style="color: #000000;">Concat(</span><span style="color: #800080;">$dataRepository</span><span style="color: #000000;">, </span><span style="color: #800000;">"</span><span style="color: #800000;">\</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #800080;">$item</span><span style="color: #000000;">.Name)<br /> <br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> ([System.IO.File]</span><span style="color: #000000;">::</span><span style="color: #000000;">Exists(</span><span style="color: #800080;">$destinationPath</span><span style="color: #000000;">) </span><span style="color: #008080;">-ne</span><span style="color: #000000;"> </span><span style="color: #0000FF;">$true</span><span style="color: #000000;">)<br /> {<br /> </span><span style="color: #800000;">"</span><span style="color: #800000;">Copying </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$item</span><span style="color: #000000;">.Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;"> to the heap...</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> <br /> [System.IO.File]</span><span style="color: #000000;">::</span><span style="color: #000000;">Copy(</span><span style="color: #800080;">$item</span><span style="color: #000000;">.FullName, </span><span style="color: #800080;">$destinationPath</span><span style="color: #000000;">)<br /> }<br /> <br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #800080;">$item</span><span style="color: #000000;">.Extension </span><span style="color: #008080;">-eq</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">.xml</span><span style="color: #800000;">"</span><span style="color: #000000;">)<br /> {<br /> </span><span style="color: #800080;">$processArgs</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$item</span><span style="color: #000000;">.FullName<br /> </span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object System.Diagnostics.ProcessStartInfo(</span><span style="color: #800080;">$importerToolPath</span><span style="color: #000000;">, </span><span style="color: #800080;">$processArgs</span><span style="color: #000000;">)<br /> </span><span style="color: #800080;">$startInfo</span><span style="color: #000000;">.UseShellExecute </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">$false</span><span style="color: #000000;"><br /><br /> </span><span style="color: #800080;">$importProcess</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> new</span><span style="color: #000000;">-</span><span style="color: #000000;">object System.Diagnostics.</span><span style="color: #0000FF;">Process</span><span style="color: #000000;">;<br /> </span><span style="color: #800080;">$importProcess</span><span style="color: #000000;">.StartInfo </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"><br /> </span><span style="color: #800080;">$startInfo</span><span style="color: #000000;"><br /> echo </span><span style="color: #800000;">"</span><span style="color: #800000;">Starting import.</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> </span><span style="color: #800080;">$importProcess</span><span style="color: #000000;">.Start()<br /><br /> </span><span style="color: #0000FF;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #800080;">$importProcess</span><span style="color: #000000;">.HasExited)<br /> {<br /> </span><span style="color: #800000;">"</span><span style="color: #800000;">[</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">$item</span><span style="color: #000000;">.Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">]</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;"> Waiting for import to complete... </span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> ([DateTime]</span><span style="color: #000000;">::</span><span style="color: #000000;">Now </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #800080;">$importProcess</span><span style="color: #000000;">.StartTime)<br /> [System.Threading.Thread]</span><span style="color: #000000;">::</span><span style="color: #000000;">Sleep(</span><span style="color: #000000;">1000</span><span style="color: #000000;">)<br /> }<br /> }<br />}<br /><br /></span><span style="color: #800080;">$sourceDirectoryInfo</span><span style="color: #000000;">.Delete(</span><span style="color: #0000FF;">$true</span><span style="color: #000000;">)</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /></p><br /><br /><p>It was such a disappointment. I’m still disappointed as I type this. Being a scripting environment for the .NET Framework, I thought it’d be so cool. The power of the .NET Framework and the freedom of scripting.</p><br /><br /><p>But the Integrated Scripting Environment (ISE) is just some crappy cobbled-together tool written in not much more time than it took me to write my script here. It even uses the atrocious code editor from the Expression suite and not the awesome editor that Noah Richards and his team made for Visual Studio 2010.</p><br /><br /><p>But worst of all, it has no IntelliSense. Can you imagine?</p><br /><br /><p>Apparently there’s PowerGUI that is a non-Microsoft ISE that does have autocomplete (which is an absolute must when you’ve all of the .NET Framework at your disposal and there’s no compiler to warn as you go), but I read something about a guy having a problem with a script which was down to the PowerGUI editor getting confused over some combination of slashes and dots, which put me right off.</p><br /><br /><p>So I punched my code into the MS ISE, almost single fingering the keys to ensure it was all correct, like I was back in the 1980s with my Sharp MZ-700.</p><br /><br /><p>And slowly my will to live drained from me.</p><br /><br /><p>I even read some dude praising it because all he needed was Notepad and Google to be a master of his universe. Not out of my pocket does an engineer work with such inefficiency. Would you take the cab if you saw that the driver was <em>peddling</em> the car through a hole in the floor?</p><br /><br /><p>Next time, I will do what I usually do and write a full blown console application in a tenth of the time.</p><br /><br /><p>If you’re a .NET developer, Hell, if you’re a sys admin (as I was for years), I’d just use Visual Studio all the way. Skip those cmdlets.</p><br /><br /><p>Get properly organised by writing and adding to an assembly of reusable components and classes to help you do your admin tasks. Get the whole department adding to a super cool library of administrative joy.</p><br /><br /><p>I came into programming from a sys admin background. I worked for a very large organisation with tens of thousands of computers. I saw the same code across so many scripts, it was a terrible duplication of effort.</p><br /><br /><p>So I cultivated a library of fine-grained admin tools in a COM component that was deployed to the PC estate and called from the scripts, a core set of reusable functionality. Then later I integrated it with a Microsoft Excel add-in. That’s right, sys admins could build out their scripts from a report in Excel, drag and drop, cut and paste. Done.</p><br /><br /><p>Anyway, I’m going off on a tangent. The benefits of PowerShell from my noob viewpoint are, simple visual remotability and a focus for vendors to create simple APIs (by way of custom cmdlets).</p><br /><br /><p>These things are important for the daily activities of a busy sys admin performing live commands, sure, but if its a automated or long scripted process you need to write, its not ideal.</p><br /><br /><p>If you’re already a programmer, then just write a proper applet in the superior tools you know and love and share it with your team. And if you’re not a programmer, skip scripting and learn C#. </p><br /><br /><p>Coding in Visual Studio will blow your mind and make you a hero.</p><br /><br /><p>Luke</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com9tag:blogger.com,1999:blog-5416778419136716668.post-81829629075263184122010-12-09T13:48:00.001-08:002010-12-09T13:48:35.341-08:00The World’s Best MessageBox Control (it maybe just a bog standard message box control to you but I like it)<p><strong>Here it is in action, recorded on a Flip Mino HD, which really doesn’t like filming anything close-by or with fine detail. But you get the picture.</strong></p> <iframe height="300" src="http://player.vimeo.com/video/17646966" frameborder="0" width="400"></iframe> <p><a href="http://vimeo.com/17646966">SimpleMessageBox for Windows Phone 7</a> from <a href="http://vimeo.com/user4951144">Luke Puplett</a> on <a href="http://vimeo.com">Vimeo</a>.</p> <p>The message box is a pretty straight forward affair, following the parts and states model. What’s possibly interesting is that the buttons are added as KeyValue<string, ICommand> pairs and rendered in the default template using a WrapPanel.</p> <p>This means its dependant on two external libraries; Laurent Bugnion’s excellent <a href="http://mvvmlight.codeplex.com/">MVVM Light Toolkit</a> and also the <a href="http://silverlight.codeplex.com/">Silverlight Toolkit for Windows Phone</a>.</p> <p>But the cool thing is that its entirely MVVM-able and the WrapPanel means that you can chuck as many buttons as you like on the page and they’ll look fabulous (darling).</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c563361e-1f71-49ef-a673-bd49550ed451" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 333px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><br /><br /></span><span style="color: #0000FF;">namespace</span><span style="color: #000000;"> Evoq.Vuplan.Mobile.Phone.Controls<br />{<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Collections.ObjectModel;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Windows;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Windows.Controls;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Collections.Generic;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Windows.Input;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> GalaSoft.MvvmLight.Command;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System;<br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Step 1a) Using this custom control in a XAML file that exists in the current project.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Add this XmlNamespace attribute to the root element of the markup file where it is <br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> to be used:<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> xmlns:MyNamespace="clr-namespace:AnimationExperiments"<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Step 1b) Using this custom control in a XAML file that exists in a different project.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Add this XmlNamespace attribute to the root element of the markup file where it is <br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> to be used:<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> xmlns:MyNamespace="clr-namespace:AnimationExperiments;assembly=AnimationExperiments"<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> You will also need to add a project reference from the project where the XAML file lives<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> to this project and Rebuild to avoid compilation errors:<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Right click on the target project in the Solution Explorer and<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> "Add Reference"->"Projects"->[Browse to and select this project]<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Step 2)<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Go ahead and use your control in the XAML file.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><MyNamespace:WindowGrip/></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;"> </span><span style="color: #808080;"><br /></span><span style="color: #000000;"> [TemplatePart(Type </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(TextBlock), Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> SimpleMessageBox.TitlePartName)]<br /> [TemplatePart(Type </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(TextBlock), Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> SimpleMessageBox.MessagePartName)]<br /> [TemplatePart(Type </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(ItemsControl), Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> SimpleMessageBox.ButtonItemsPartName)]<br /> [TemplateVisualState(GroupName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">VisibilityStates</span><span style="color: #800000;">"</span><span style="color: #000000;">, Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> SimpleMessageBox.CollapsedStateName)] </span><span style="color: #008000;">//</span><span style="color: #008000;"> Default</span><span style="color: #008000;"><br /></span><span style="color: #000000;"> [TemplateVisualState(GroupName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">VisibilityStates</span><span style="color: #800000;">"</span><span style="color: #000000;">, Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> SimpleMessageBox.VisibleStateName)]<br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> SimpleMessageBox : Control<br /> {<br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Fields</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> _currentState </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">stateSetInOnApplyTemplate</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Constants</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> TitlePartName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">TitlePart</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> MessagePartName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">MessagePart</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> ButtonItemsPartName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">ButtonItemsPart</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> CollapsedStateName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Collapsed</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> VisibleStateName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Visible</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Dependency Property Backers</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">readonly</span><span style="color: #000000;"> DependencyProperty IsCollapsedProperty </span><span style="color: #000000;">=</span><span style="color: #000000;"><br /> DependencyProperty.Register(</span><span style="color: #800000;">"</span><span style="color: #800000;">IsCollapsed</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(</span><span style="color: #0000FF;">bool</span><span style="color: #000000;">), </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(SimpleMessageBox),<br /> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyMetadata(</span><span style="color: #0000FF;">true</span><span style="color: #000000;">, </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyChangedCallback(HandleCollapsedChanged)));<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">readonly</span><span style="color: #000000;"> DependencyProperty TitleProperty </span><span style="color: #000000;">=</span><span style="color: #000000;"><br /> DependencyProperty.Register(</span><span style="color: #800000;">"</span><span style="color: #800000;">Title</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(</span><span style="color: #0000FF;">string</span><span style="color: #000000;">), </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(SimpleMessageBox),<br /> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyMetadata(</span><span style="color: #800000;">"</span><span style="color: #800000;">Alert</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">readonly</span><span style="color: #000000;"> DependencyProperty MessageProperty </span><span style="color: #000000;">=</span><span style="color: #000000;"><br /> DependencyProperty.Register(</span><span style="color: #800000;">"</span><span style="color: #800000;">Message</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(</span><span style="color: #0000FF;">string</span><span style="color: #000000;">), </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(SimpleMessageBox),<br /> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyMetadata(</span><span style="color: #800000;">"</span><span style="color: #800000;">You need to set a message to display, even if it is an empty string.</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">readonly</span><span style="color: #000000;"> DependencyProperty ButtonsProperty </span><span style="color: #000000;">=</span><span style="color: #000000;"><br /> DependencyProperty.Register(</span><span style="color: #800000;">"</span><span style="color: #800000;">Buttons</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;">), </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(SimpleMessageBox),<br /> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyMetadata(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;">()));<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Constructors</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> SimpleMessageBox()<br /> {<br /> </span><span style="color: #008000;">//</span><span style="color: #008000;"> DefaultStyleKeyProperty.OverrideMetadata(typeof(StatefulImage), new FrameworkPropertyMetadata(typeof(StatefulImage))); </span><span style="color: #008000;"><br /></span><span style="color: #000000;"> }<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> SimpleMessageBox()<br /> : </span><span style="color: #0000FF;">base</span><span style="color: #000000;">()<br /> {<br /> DefaultStyleKey </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.GetType();<br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Buttons </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;">();<br /><br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (DesignerHelper.GetIsInDesignMode())<br /> {<br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Buttons.Add(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">></span><span style="color: #000000;">(</span><span style="color: #800000;">"</span><span style="color: #800000;">test</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RelayCommand(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> Action(() </span><span style="color: #000000;">=></span><span style="color: #000000;"> { }))));<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Properties</span><span style="color: #000000;"><br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Gets or sets a value that indicates whether or not the message box is collapsed.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> IsCollapsed<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">bool</span><span style="color: #000000;">)GetValue(IsCollapsedProperty); }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"> { SetValue(IsCollapsedProperty, value); }<br /> }<br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Gets or sets the title of the message box.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Title<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">string</span><span style="color: #000000;">)GetValue(TitleProperty); }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"> { SetValue(TitleProperty, value); }<br /> }<br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Gets or sets the message in the message box.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Message<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">string</span><span style="color: #000000;">)GetValue(MessageProperty); }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"> { SetValue(MessageProperty, value); }<br /> }<br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Gets or sets a collection of the buttons on the message box.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;"> Buttons<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> (ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;">)GetValue(ButtonsProperty); }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"> { SetValue(ButtonsProperty, value); }<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Methods</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> HandleCollapsedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)<br /> {<br /> var control </span><span style="color: #000000;">=</span><span style="color: #000000;"> (SimpleMessageBox)sender; <br /><br /> control.UpdateStates(</span><span style="color: #0000FF;">true</span><span style="color: #000000;">);<br /> }<br /><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Reads properties and fires off the state changer using VSM.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><param name="useTransitions"></span><span style="color: #008000;">Whether to trigger animations between the states.</span><span style="color: #808080;"></param></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> UpdateStates(</span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> useTransitions)<br /> {<br /> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> state </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.IsCollapsed </span><span style="color: #000000;">?</span><span style="color: #000000;"> CollapsedStateName : VisibleStateName;<br /><br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (_currentState </span><span style="color: #000000;">!=</span><span style="color: #000000;"> state)<br /> {<br /> _currentState </span><span style="color: #000000;">=</span><span style="color: #000000;"> state;<br /> VisualStateManager.GoToState(</span><span style="color: #0000FF;">this</span><span style="color: #000000;">, state, useTransitions);<br /> }<br /> }<br /> <br /> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> page_BackKeyPress(</span><span style="color: #0000FF;">object</span><span style="color: #000000;"> sender, System.ComponentModel.CancelEventArgs e)<br /> {<br /> e.Cancel </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">!</span><span style="color: #0000FF;">this</span><span style="color: #000000;">.IsCollapsed;<br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.IsCollapsed </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">;<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Control Overrides</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> OnApplyTemplate()<br /> {<br /> </span><span style="color: #0000FF;">base</span><span style="color: #000000;">.OnApplyTemplate();<br /><br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.UpdateStates(</span><span style="color: #0000FF;">false</span><span style="color: #000000;">);<br /> <br /> </span><span style="color: #0000FF;">try</span><span style="color: #000000;"><br /> {<br /> FrameworkElement p </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">;<br /> </span><span style="color: #0000FF;">while</span><span style="color: #000000;"> (</span><span style="color: #000000;">!</span><span style="color: #000000;">(p </span><span style="color: #0000FF;">is</span><span style="color: #000000;"> PhoneApplicationPage))<br /> p </span><span style="color: #000000;">=</span><span style="color: #000000;"> p.Parent </span><span style="color: #0000FF;">as</span><span style="color: #000000;"> FrameworkElement;<br /><br /> var page </span><span style="color: #000000;">=</span><span style="color: #000000;"> (PhoneApplicationPage)p;<br /> page.BackKeyPress </span><span style="color: #000000;">+=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> EventHandler</span><span style="color: #000000;"><</span><span style="color: #000000;">System.ComponentModel.CancelEventArgs</span><span style="color: #000000;">></span><span style="color: #000000;">(page_BackKeyPress);<br /> }<br /> </span><span style="color: #0000FF;">catch</span><span style="color: #000000;"><br /> { }<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /> }<br />}<br /></span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br />This should be all that’s needed in the Themes\generic.xaml to set its default skin.<br /><br /><br /><br /><br /><br /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:21aa809e-ac48-4d55-9a64-4002dc8a5285" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 292px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><</span><span style="color: #000000;">ResourceDictionary<br /> xmlns</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">http://schemas.microsoft.com/winfx/2006/xaml/presentation</span><span style="color: #800000;">"</span><span style="color: #000000;"> <br /> xmlns:x</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">http://schemas.microsoft.com/winfx/2006/xaml</span><span style="color: #800000;">"</span><span style="color: #000000;"> <br /> xmlns:windows</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:System.Windows;assembly=System.Windows</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> xmlns:local</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:YourControlNamespace;assembly=YourControlsAssembly</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> xmlns:toolkit</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> xmlns:i</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> xmlns:cmd</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> xmlns:unsupported</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:Microsoft.Phone.Controls.Unsupported</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> </span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><!--</span><span style="color: #000000;"> Resource dictionary entries should be defined here. </span><span style="color: #000000;">--></span><span style="color: #000000;"><br /><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Style TargetType</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">local:SimpleMessageBox</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter Property</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Background</span><span style="color: #800000;">"</span><span style="color: #000000;"> Value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{StaticResource PhoneChromeBrush}</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter Property</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">BorderBrush</span><span style="color: #800000;">"</span><span style="color: #000000;"> Value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Transparent</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter Property</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">BorderThickness</span><span style="color: #800000;">"</span><span style="color: #000000;"> Value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter Property</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Padding</span><span style="color: #800000;">"</span><span style="color: #000000;"> Value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter Property</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Template</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Setter.Value</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">ControlTemplate TargetType</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">local:SimpleMessageBox</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Canvas</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualStateManager.VisualStateGroups</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualStateGroup x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">VisibilityStates</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualStateGroup.Transitions</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualTransition GeneratedDuration</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0:0:0.3</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualTransition.GeneratedEasingFunction</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">BackEase EasingMode</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">EaseOut</span><span style="color: #800000;">"</span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualTransition.GeneratedEasingFunction</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualTransition</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualStateGroup.Transitions</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualState x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Collapsed</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Storyboard</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">DoubleAnimation Duration</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0</span><span style="color: #800000;">"</span><span style="color: #000000;"> To</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">-90</span><span style="color: #800000;">"</span><span style="color: #000000;"> Storyboard.TargetProperty</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">(UIElement.Projection).(PlaneProjection.RotationX)</span><span style="color: #800000;">"</span><span style="color: #000000;"> Storyboard.TargetName</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">MessageBoard</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Storyboard</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualState</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">VisualState x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Visible</span><span style="color: #800000;">"</span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualStateGroup</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">VisualStateManager.VisualStateGroups</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Grid x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">MessageBoard</span><span style="color: #800000;">"</span><span style="color: #000000;"> Background</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{TemplateBinding Background}</span><span style="color: #800000;">"</span><span style="color: #000000;"> Width</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{TemplateBinding Width}</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Grid.Projection</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">PlaneProjection</span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Grid.Projection</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">StackPanel Margin</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">15</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">TextBlock x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">TitlePart</span><span style="color: #800000;">"</span><span style="color: #000000;"> FontSize</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{StaticResource PhoneFontSizeLarge}</span><span style="color: #800000;">"</span><span style="color: #000000;"> FontFamily</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{StaticResource PhoneFontFamilyNormal}</span><span style="color: #800000;">"</span><span style="color: #000000;"> <br /> Text</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{TemplateBinding Title}</span><span style="color: #800000;">"</span><span style="color: #000000;"> TextWrapping</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Wrap</span><span style="color: #800000;">"</span><span style="color: #000000;"> Margin</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0,0,0,5</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">TextBlock x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">MessagePart</span><span style="color: #800000;">"</span><span style="color: #000000;"> FontSize</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{StaticResource PhoneFontSizeMedium}</span><span style="color: #800000;">"</span><span style="color: #000000;"> FontFamily</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{StaticResource PhoneFontFamilyLight}</span><span style="color: #800000;">"</span><span style="color: #000000;"> <br /> Text</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{TemplateBinding Message}</span><span style="color: #800000;">"</span><span style="color: #000000;"> TextWrapping</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Wrap</span><span style="color: #800000;">"</span><span style="color: #000000;"> Margin</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">0,0,0,16</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">ItemsControl x:Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">ButtonItemsPart</span><span style="color: #800000;">"</span><span style="color: #000000;"> ItemsSource</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{TemplateBinding Buttons}</span><span style="color: #800000;">"</span><span style="color: #000000;"> Margin</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">-15,0</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">ItemsControl.ItemsPanel</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">ItemsPanelTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">toolkit:WrapPanel Orientation</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Horizontal</span><span style="color: #800000;">"</span><span style="color: #000000;"> HorizontalAlignment</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Left</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">ItemsPanelTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">ItemsControl.ItemsPanel</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">ItemsControl.ItemTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">DataTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">Button MinWidth</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">238</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">TextBlock Text</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding Key}</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">i:Interaction.Triggers</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">i:EventTrigger EventName</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Click</span><span style="color: #800000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"><</span><span style="color: #000000;">cmd:EventToCommand Command</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding Value}</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">i:EventTrigger</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">i:Interaction.Triggers</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Button</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">DataTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">ItemsControl.ItemTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">ItemsControl</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">StackPanel</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Grid</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Canvas</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">ControlTemplate</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Setter.Value</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Setter</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">Style</span><span style="color: #000000;">></span><span style="color: #000000;"><br /><br /><br /></span><span style="color: #000000;"></</span><span style="color: #000000;">ResourceDictionary</span><span style="color: #000000;">></span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /><br /><br /><br /><p>And there are two snippets here that demonstrate the control, but are otherwise not required.</p><br /><br /><br /><br /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:ec83d88e-61a5-4be2-9ade-da79ab397792" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 338px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"> </span><span style="color: #008000;">//</span><span style="color: #008000;"> In Page ViewModel ctor or some method.<br /> <br /> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Tests the control by constantly transitioning.</span><span style="color: #008000;"><br /></span><span style="color: #000000;"> <br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> MessageBoxViewModel()<br /> {<br /> Title </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Test run-time data</span><span style="color: #800000;">"</span><span style="color: #000000;">,<br /> Message </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">This message text is inserted in the constructor of the view model.</span><span style="color: #800000;">"</span><span style="color: #000000;">,<br /> ControlVisibility </span><span style="color: #000000;">=</span><span style="color: #000000;"> Visibility.Visible,<br /> };<br /><br /> var exit </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RelayCommand( () </span><span style="color: #000000;">=></span><span style="color: #000000;"> { _t.Change(</span><span style="color: #800080;">0</span><span style="color: #000000;">, </span><span style="color: #800080;">0</span><span style="color: #000000;">); } );<br /><br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox.ButtonCommandPairs.Add(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, System.Windows.Input.ICommand</span><span style="color: #000000;">></span><span style="color: #000000;">(</span><span style="color: #800000;">"</span><span style="color: #800000;">run</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #0000FF;">null</span><span style="color: #000000;">));<br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox.ButtonCommandPairs.Add(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, System.Windows.Input.ICommand</span><span style="color: #000000;">></span><span style="color: #000000;">(</span><span style="color: #800000;">"</span><span style="color: #800000;">time</span><span style="color: #800000;">"</span><span style="color: #000000;">, exit));<br /><br /> _t </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> System.Threading.Timer(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> System.Threading.TimerCallback((state) </span><span style="color: #000000;">=></span><span style="color: #000000;"><br /> {<br /> _log.Debug(</span><span style="color: #800000;">"</span><span style="color: #800000;">Timer</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br /><br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox.IsCollapsed)<br /> Deployment.Current.Dispatcher.BeginInvoke( () </span><span style="color: #000000;">=></span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox.IsCollapsed </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;"> );<br /> </span><span style="color: #0000FF;">else</span><span style="color: #000000;"><br /> Deployment.Current.Dispatcher.BeginInvoke(() </span><span style="color: #000000;">=></span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.MessageBox.IsCollapsed </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">);<br /><br /> }), </span><span style="color: #0000FF;">null</span><span style="color: #000000;">, </span><span style="color: #800080;">1000</span><span style="color: #000000;">, </span><span style="color: #800080;">1000</span><span style="color: #000000;">);<br /> <br /> <br /> </span><span style="color: #008000;">//</span><span style="color: #008000;"> In ViewModel somewhere:</span><span style="color: #008000;"><br /></span><span style="color: #000000;"> <br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> MessageBoxViewModel MessageBox { </span><span style="color: #0000FF;">get</span><span style="color: #000000;">; </span><span style="color: #0000FF;">set</span><span style="color: #000000;">; }</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /><br /><br /><br /><p>This is the view model for the message box and is usually exposed as a property of the page’s view model (note above the this.MessageBox property being set).</p><br /><br /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:b636586e-7d5a-42b2-9307-2b847b6d8282" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 338px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><br /><br /></span><span style="color: #0000FF;">namespace</span><span style="color: #000000;"> Evoq.Vuplan.Mobile.Phone.ViewModels<br />{<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Collections.Generic;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Collections.ObjectModel;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.ComponentModel;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Windows;<br /> </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Windows.Input;<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> MessageBoxViewModel : INotifyPropertyChanged<br /> {<br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Fields</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Events and OnMethods</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">event</span><span style="color: #000000;"> PropertyChangedEventHandler PropertyChanged;<br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> NotifyPropertyChanged(String propertyName)<br /> {<br /> PropertyChangedEventHandler handler </span><span style="color: #000000;">=</span><span style="color: #000000;"> PropertyChanged;<br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">null</span><span style="color: #000000;"> </span><span style="color: #000000;">!=</span><span style="color: #000000;"> handler)<br /> {<br /> handler(</span><span style="color: #0000FF;">this</span><span style="color: #000000;">, </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> PropertyChangedEventArgs(propertyName));<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Constructors</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> MessageBoxViewModel()<br /> {<br /> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.ButtonCommandPairs </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;">();<br /> }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">#region</span><span style="color: #000000;"> Properties</span><span style="color: #000000;"><br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> _title;<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Sample ViewModel property; this property is used in the view to display its value using a Binding.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><returns></returns></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Title<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _title;<br /> }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (value </span><span style="color: #000000;">!=</span><span style="color: #000000;"> _title)<br /> {<br /> _title </span><span style="color: #000000;">=</span><span style="color: #000000;"> value;<br /> NotifyPropertyChanged(</span><span style="color: #800000;">"</span><span style="color: #800000;">Title</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br /> }<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> _message;<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Sample ViewModel property; this property is used in the view to display its value using a Binding.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><returns></returns></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Message<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _message;<br /> }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (value </span><span style="color: #000000;">!=</span><span style="color: #000000;"> _message)<br /> {<br /> _message </span><span style="color: #000000;">=</span><span style="color: #000000;"> value;<br /> NotifyPropertyChanged(</span><span style="color: #800000;">"</span><span style="color: #800000;">Message</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br /> }<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> _isCollapsed;<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Sample ViewModel property; this property is used in the view to display its value using a Binding.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> IsCollapsed<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _isCollapsed;<br /> }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (value </span><span style="color: #000000;">!=</span><span style="color: #000000;"> _isCollapsed)<br /> {<br /> _isCollapsed </span><span style="color: #000000;">=</span><span style="color: #000000;"> value;<br /> NotifyPropertyChanged(</span><span style="color: #800000;">"</span><span style="color: #800000;">IsCollapsed</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br /> }<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> Visibility _controlVisibility;<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> Sample ViewModel property; this property is used in the view to display its value using a Binding.<br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;"><br /> </span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><returns></returns></span><span style="color: #808080;"><br /></span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> Visibility ControlVisibility<br /> {<br /> </span><span style="color: #0000FF;">get</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _controlVisibility;<br /> }<br /> </span><span style="color: #0000FF;">set</span><span style="color: #000000;"><br /> {<br /> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (value </span><span style="color: #000000;">!=</span><span style="color: #000000;"> _controlVisibility)<br /> {<br /> _controlVisibility </span><span style="color: #000000;">=</span><span style="color: #000000;"> value;<br /> NotifyPropertyChanged(</span><span style="color: #800000;">"</span><span style="color: #800000;">ControlVisibility</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br /> }<br /> }<br /> }<br /><br /> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> ObservableCollection</span><span style="color: #000000;"><</span><span style="color: #000000;">KeyValuePair</span><span style="color: #000000;"><</span><span style="color: #0000FF;">string</span><span style="color: #000000;">, ICommand</span><span style="color: #000000;">>></span><span style="color: #000000;"> ButtonCommandPairs { </span><span style="color: #0000FF;">get</span><span style="color: #000000;">; </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">set</span><span style="color: #000000;">; }<br /><br /> </span><span style="color: #0000FF;">#endregion</span><span style="color: #000000;"><br /> }<br />}</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /><br /><p>This lump of XAML shows how to declare the control on a page. The thing which is important here is to use TwoWay binding because the SimpleMessageBox control itself can change the IsCollapsed property internally when handling the back button key.</p><br /><br /><br /><br /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:48a4d4c3-c9af-4a36-bee7-a021f42b962e" class="wlWriterEditableSmartContent"><pre style=" width: 623px; height: 118px;background-color:White;overflow: auto;"><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"> </span><span style="color: #000000;"><</span><span style="color: #000000;">controllib:SimpleMessageBox DataContext</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding MessageBox}</span><span style="color: #800000;">"</span><span style="color: #000000;"> <br /> Title</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding Title}</span><span style="color: #800000;">"</span><span style="color: #000000;"> Message</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding Message}</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> Buttons</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding ButtonCommandPairs}</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> Width</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding ElementName=LayoutRoot, Path=ActualWidth}</span><span style="color: #800000;">"</span><span style="color: #000000;"><br /> IsCollapsed</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">{Binding IsCollapsed, Mode=TwoWay}</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/></span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /><br /><br /><br /><p>Merry Christmas!</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com2tag:blogger.com,1999:blog-5416778419136716668.post-28633343963848319192010-11-21T04:55:00.001-08:002010-11-21T04:55:35.741-08:00Helpful docs when hardening an IIS web server<p>While clearing up some crap on my desktop I came across a note listing some documents I’d used when preparing my web server for co-location and exposure to the harshness of the public internet.</p> <p>How To: Harden the TCP/IP Stack <br /><a href="http://msdn.microsoft.com/en-us/library/ff648853.aspx">http://msdn.microsoft.com/en-us/library/ff648853.aspx</a></p> <p>TCP Receive Window Size and Window Scaling <br /><a href="http://msdn.microsoft.com/en-us/library/ms819736.aspx">http://msdn.microsoft.com/en-us/library/ms819736.aspx</a></p> <p>How To: Protect Forms Authentication in ASP.NET 2.0 <br /><a href="http://msdn.microsoft.com/en-us/library/ff648341.aspx">http://msdn.microsoft.com/en-us/library/ff648341.aspx</a></p> <p>How To: Perform a Security Deployment Review for ASP.NET 2.0 <br /><a href="http://msdn.microsoft.com/en-us/library/ff647403.aspx">http://msdn.microsoft.com/en-us/library/ff647403.aspx</a></p> <p>How To: Use IPSec for Filtering Ports and Authentication <br /><a href="http://msdn.microsoft.com/en-us/library/ff648481.aspx">http://msdn.microsoft.com/en-us/library/ff648481.aspx</a></p> <p>How To: Use IISLockdown.exe <br /><a href="http://msdn.microsoft.com/en-us/library/ff650415.aspx">http://msdn.microsoft.com/en-us/library/ff650415.aspx</a></p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-51090644225851267172010-11-15T08:01:00.001-08:002010-11-15T08:01:34.462-08:00Detecting Windows Phone Screen Size<p>Eventually, and probably not long from now, the Windows Phone will have a form factor that isn’t 480 x 800 so here’s how to detect the screen size:</p> <pre>protected PhoneViewModel()<br />{<br />    this.ScreenWidth = System.Windows.Application.Current.Host.Content.ActualWidth;<br />    this.ScreenHeight = System.Windows.Application.Current.Host.Content.ActualHeight;<br />}</pre> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-19728249263575791772010-11-05T09:32:00.001-07:002010-11-05T09:32:32.746-07:00The (dis)appearance of ‘Spaghetti Code’ in ASPX views<p><strong>Offended by the proliferation of vulgar </strong><font style="background-color: #ffff00"><%</font><font style="background-color: #ffff00"></font><strong><font style="style"> throughout my view mark-up, and with no luck/patience getting Razor working, I decided that the poor man’s version would be to tone-down those ugly little marks. The result was quite amazing.</font></strong></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwJ_T-skEee5w7eedAYj_knZoSWksoszM6hsj7ehyphenhyphenw6pbgSp3RocOj5ZCUf9q0SQQzrqDBfxVQkB7Qosjjf6YaZ3WbVrmQfx2-QbMmPloIaj_sYr6oNC2_J9lmAVbRDXOSDIIrrXpuoRBy/s1600-h/Capture%5B3%5D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Capture" border="0" alt="Capture" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAl7RbON6LliS2Ij7YVZIxeAxJ7A6C2j_Gqaw_Wa5xAeHQPAv_k4WnzW8GZUO62h9-fFEpJF6I7InwEjFkO5br1TLAY8vSGKsuZUnWCMiIwVD9R8b_49JouVMknIW6sCZwZBdpnl7eDYbW/?imgmax=800" width="565" height="336" /></a></p> <p>The tags denoting server-side code no longer wrestle for attention and send my eyes spinning. I almost didn’t post this but I’d wager that most people out there would blame the hard readability on the way ASP.NET MVC works and not the poor choice of colour in the default settings.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-76506034777714142462010-10-31T16:49:00.001-07:002010-10-31T16:49:40.792-07:00My Gestural ScrollViewer in vuPlan.tv Client<iframe height="1220" src="http://player.vimeo.com/video/15782239" frameborder="0" width="636"></iframe> <p><a href="http://vimeo.com/15782239">vuPlan.tv Client Gestural UI - WPF</a> from <a href="http://vimeo.com/user4951144">Luke Puplett</a> on <a href="http://vimeo.com">Vimeo</a>.</p> <p>Pretty huge, I know, I know. I don’t even think Vimeo scales it.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-21935062421554564412010-10-28T05:04:00.001-07:002010-10-28T05:07:30.364-07:00Windows Phone 7, Windows 8 and Not-Desking<p><strong>Smug. That’s how early iPhone users felt they up went home, or into work, with their shiny world-in-a-box gadgets. And this is how I feel as the new owner of a Samsung Omnia Windows Phone 7 device.</strong></p> <p>My first impression is that it is at least twice as good to look at and hold than I expected, and superior in feel than the aforementioned revolutionary. Or maybe its the novelty of change.</p> <p>I won’t bore you and myself with a guide around it but I wanted to write about the thoughts it provoked within a few moments of using this new phone from Ford. I mean, Microsoft.</p> <p>It makes you wonder what Windows desktop could be if it were rebuilt from the ground-up with selected hardware partners. Their desktop OS hasn’t changed much since I was a Windows support guy for them in 1997. Actually, the file system goes back to 1993.</p> <p>Then there’s the registry from Windows 3.1. Oh and don’t forget the whole network OS; slow roaming profiles, domains, NetBIOS and the rest. Maybe it’s just me but I’ve become quite contemptuous of Redmond’s laziness when I logon in the morning.</p> <p>I started my career on the frontline for Microsoft just after passing my driving test, but while I’m going grey and groaning when I ease down into my chair, Windows is still the bloody same. </p> <p>Worryingly, I’ve invented a theory on why the Windows we’ve always known may just be the only Windows we ever get. Here’s why.</p> <p>The ball around Microsoft’s ankle is its success. It has a generation of compatibility to nurse. With all it’s customers riding on its back, it must turn slowly to ensure a comfy ride. Their turning circle is perhaps wider than the twisty-changey road of technology. What to do?</p> <p>One strategy would be to build Windows 10 with no legacy support, a .NET Framework CLR and Microsoft’s own apps, then allow people to migrate in their own time, which is effectively how Windows 95 became NT 4.0 became Windows XP.</p> <p>This would be costly in the sense that they’d be supporting two Windows lines but keeping everyone happy. The Ford Galaxy and the Ford Focus RS.</p> <p>Or I wonder if the desktop will actually be left to fester as the world of devices takes over and desktop computing becomes a niche in a liberated new world where workers don’t just hot-desk, but not-desk.</p> <p>To make the Focus RS, is it worth the significant financial investment, upheaval and disruption to their massive customer base at a time when their future is so uncertain? Uncertain because of the interesting situation they’ve woken up to find themselves in.</p> <p>Technological innovation has the biggest impact on human behavioural trends, and while Microsoft were scrimping on their mobile platform, also just an old codebase with a coat of paint, their ability to control and pre-empt future trends was also lost.</p> <p>Windows may have won out in the desktop era but they’re arguably just starting out, behind not one but two other companies, in the next era of computing.</p> <p>So Microsoft is in the unfamiliar position of having to take an, albeit very experienced, guess on how people will go about their lives and business in the coming couple of decades.</p> <p>Interesting times.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-34602999978911534282010-10-12T03:29:00.001-07:002010-10-12T03:40:12.006-07:00Note to Self: Covariance and Contravariance in a Nutshell<p>On Channel9, the academic interviews are very stimulating but they tend to confuse a simple concept in theoretical mumbo-jumbo.</p> <p>Covariance is the ability to upcast a collection of types to a collection of more primitive classes.</p> <p>Sorry about the small font, some crappy CSS somewhere.</p> <p><code>IEnumerable<Truck><truck> trucks = TruckRepository.Trucks.Where(t => t.Color == Red);</code></p> <p><code>IEnumerable<Vehicle> <vehicle>vehicles = trucks as IEnumerable<Vehicle><vehicle>;</code></p> <p>But it only works with IEnumerable<T> because the collection is read-only. If it didn’t have this constraint, then we’d be able to do this to a List and then add a Car, and that’d be bad because its still really a collection of Truck.</p> <p>Contravariance is obviously the opposite, when things go in (and so less to do with collections), the type can be cast to be more specific (say, Action<Vehicle> to Action<Truck> and it will happily accept a Truck because its a vehicle.</p> <p>Func<T, TResult> is more interesting because its got generic T in and TResult out types. This means that the T is contravariant on the way in and the TResult is covariant as it comes out.</p> <p>Variance doesn’t come automatically.</p> <p>Should you wish to allow covariance, the T must be marked with the out keyword; <strong>out T</strong>. And obviously <strong>in T </strong>defines and contravariant generic type param. You can’t put out T on an interface method because it method params are implicitly inbound.</p> <p>Co out. Contra in.</p> <p>Microsoft have added out and in to a whole bunch of interfaces and delegates which is why it appears to come automatically with .NET 4.0.</p> <p><a href="http://msdn.microsoft.com/en-us/library/dd799517.aspx">http://msdn.microsoft.com/en-us/library/dd799517.aspx</a></p> <p>Restrictions (from MSDN):</p> <ul> <li> <p>In the .NET Framework version 4, variant type parameters are restricted to generic interface and generic delegate types.</p> </li> <li> <p>A generic interface or generic delegate type can have both covariant and contravariant type parameters.</p> </li> <li> <p>Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.</p> </li> <li> <p>Variance does not apply to delegate combination. That is, given two delegates of types Action<Derived> andAction<Base> (Action(Of Derived) and Action(Of Base) in Visual Basic), you cannot combine the second delegate with the first although the result would be type safe. Variance allows the second delegate to be assigned to a variable of typeAction<Derived>, but delegates can combine only if their types match exactly.</p> </li> </ul> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com1tag:blogger.com,1999:blog-5416778419136716668.post-6769211661729247052010-10-09T06:04:00.001-07:002010-10-09T06:04:15.836-07:00Task Parallel Library Cheat Sheet<p>While I’d followed Mr Toub and his gang while they were making the TPL, I’ve since slept and forgotten it all. So I can always consider a concurrent approach to my classes, I thought I’d make a very simple overview ‘cheat sheet’ and stick it to the wall.</p> <p>Get it <a href="http://cid-db71be93ce07377a.office.live.com/self.aspx/.Public/TPL%20Cheat%20Sheet%20v1.pdf">here</a>.</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0tag:blogger.com,1999:blog-5416778419136716668.post-20098492080389685792010-10-07T06:49:00.001-07:002010-10-07T06:49:27.677-07:00Recent Changes to vuPlan.tv Client<p>Since writing vuPlan.tv I’ve been using a placeholder company name ‘S26’ which I had to refactor to reflect my final company name Evoq Limited. The new codebase is built with new filenames and namespaces.</p> <p>Also, the Windows 7 implementation of the Media Center API, at the COM interop level, has a memory leak. The new client works around the problem by creating an API shim inside a new AppDomain which gets recycled at intervals.</p> <p>Finally, after seeing Mike Taulty’s session at UK Tech Days and his showing-off of new Metro-esque Windows 7 WPF applications Zune and MetroTwit, I reverted the vuPlan.tv client back into its Metro pyjamas. Previously I’d not done enough work on the shadow which is why it never really rocked my world; this version is much better I think.</p> <a title="vuPlan.tv Funkier Metro Look by lukepuplett, on Flickr" href="http://www.flickr.com/photos/22787790@N06/5059942058/"><img alt="vuPlan.tv Funkier Metro Look" src="http://farm5.static.flickr.com/4103/5059942058_3406dce174.jpg" width="246" height="500" /></a> <p>Testing is on-going as it work on the web application/site. And that reminds me, I must update the images on the site.</p> <p>Luke</p> Luke Pupletthttp://www.blogger.com/profile/08367127592060126449noreply@blogger.com0