tag:blogger.com,1999:blog-64064422778616899632024-03-08T21:59:20.820+00:00Software and meJosephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-6406442277861689963.post-29010096882475904492015-03-11T23:53:00.001+00:002015-03-12T00:04:07.858+00:00Why does my DataTable merge not work?<p dir="ltr">I was recently looking and some older <u>DataTable</u> code.<br>
We were trying to merge an updated DataRow into an existing DataTable <br>
But... it was having non of it - the changes didn't go in.</p>
<p dir="ltr">After some hunting it turned out that the RowState of both the existing and updated rows was "Modified".<br>
So the merge didn't know what to do - what takes precedence?</p>
<p dir="ltr">The solution was to call AcceptChanges() on the existing DataTable before merging in the new data.<br>
AccepChanges sets the RowState to <b>Unchanged </b>and the merge now knows what to do.</p>
<p dir="ltr">Job done!</p>
Josephhttp://www.blogger.com/profile/06376242778178384993noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-30816164344600865092012-07-16T23:43:00.002+01:002012-07-16T23:43:45.825+01:00Asynchronous WCF using the generated service interface<span style="font-family: Arial, Helvetica, sans-serif;">Using Asynchronous WCF in an IoC style presents an interesting challenge.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Normal examples show that you can call async WCF something like this...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Service1Client iService1 = new Service1Client();<br />
iService1.GetDataCompleted += iService1_GetDataCompleted;<br />
iService1.GetDataAsync();</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">i.e. you declare the service client implementation, specify the callback and make the async call.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">But... what if you want to inject the client reference, for example (using Ninject):</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">[Inject]</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">IService1 iService1 {get; set;}</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">where Service1 is the interface.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Well, you find that the xxxCompleted event and xxxAsync method are not available on the interface. Ouch!</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">But, all is not lost...</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">You do have two other methods... <span style="background-color: white;">Beginxxxx and Endxxxx and you can use them as in the example below. </span></span><span style="background-color: white; font-family: Arial, Helvetica, sans-serif;">In the Beginxxxx method you specify the callback and in the callback you can get hold of the result by </span><span style="background-color: white; font-family: Arial, Helvetica, sans-serif;">calling Endxxxx</span><br />
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Note </b>that in the example below, I haven't injected the Service client, but I am using the interface, IService1. The code produces the following output (with the "Waited" appearing after the calling thread has slept for 5 seconds) :</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">Making call</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;"> Got result</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;"> You entered: 200</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;"> Waited</span><br />
<br />
<pre style="background-color: white; font-size: 13px;"><span style="font-family: 'Trebuchet MS', sans-serif;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Program</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)
{
MakeAsynchronousCall(200);
}
<span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> MakeAsynchronousCall(<span style="color: blue;">int</span> value)
{
<span style="color: #2b91af;">IService1</span> iService1 = <span style="color: blue;">new</span> <span style="color: #2b91af;">Service1Client</span>();
<span style="color: #2b91af;">AsyncCallback</span> aSyncCallBack =
<span style="color: blue;">delegate</span>(<span style="color: #2b91af;">IAsyncResult</span> result)
{
<span style="color: blue;">try</span>
{
<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Got result"</span>);
<span style="color: blue;">var</span> i = iService1.EndGetData(result);
<span style="color: #2b91af;">Console</span>.WriteLine(i);
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> ex)
{
<span style="color: #2b91af;">Console</span>.WriteLine(ex.Message);
}
};
<span style="color: blue;">try</span>
{
<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Making call"</span>);
iService1.BeginGetData(value, aSyncCallBack, iService1);
<span style="color: #2b91af;">Thread</span>.Sleep(5000);
<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Waited"</span>);
<span style="color: #2b91af;">Console</span>.ReadLine();
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> ex)
{
<span style="color: #2b91af;">MessageBox</span>.Show(ex.Message);
}
}
}</span></pre>
<pre style="background-color: white; font-size: 13px;"><span style="font-family: Arial, Helvetica, sans-serif;">
</span></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">The Server-side code is :</span>
<br />
<pre style="background-color: white; font-size: 13px;"><pre style="background-color: white;"><span style="font-family: 'Trebuchet MS', sans-serif;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> GetData(<span style="color: blue;">int</span> value)
{
<span style="color: blue;">return</span> <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"You entered: </span><span style="color: mediumseagreen;">{0}</span><span style="color: #a31515;">"</span>, value);
}</span></pre>
</pre>Josephhttp://www.blogger.com/profile/06376242778178384993noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-12080753692282100832012-02-23T00:13:00.001+00:002012-02-23T00:13:58.049+00:00Primary Keys in Entity Framework and Sync Framework - Part 2<div style="font-family: Arial,Helvetica,sans-serif;">In <a href="http://www.blogger.com/blogger.g?blogID=6406442277861689963#editor/target=post;postID=1511400007701934760">Part 1</a> we considered various options when it came to using Microsoft Sync Framework with Entity Framework.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div><div style="font-family: Arial, Helvetica, sans-serif;">After a certain amount of pain we seem to have got to something approaching a settled condition.</div><ol><li><span style="font-family: Arial, Helvetica, sans-serif;">We didn't want IDs that were GUIDs as this would make them unreadable. So, we </span><span style="font-family: Arial, Helvetica, sans-serif;">are keeping Primary keys as simple ID columns.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Because of this, we went for a solution that would reseed the local tables on each client to a known range. After each synchronisation, the tables would be reseeded to the correct value. That way entries created on the client/server would have different IDs and wouldn't clash</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">We had to use SQL Server Express on the clients.</span></li>
</ol></div><div style="font-family: Arial,Helvetica,sans-serif;">Number (3) above is a long story...</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
<ul><li>SQL Compact 4 won't play nicely with Entity Framework or the Sync Framework (<a href="http://blogs.msdn.com/b/sqlservercompact/archive/2011/03/15/sql-server-compact-4-0-tooling-support-in-visual-studio-2010-sp1-and-visual-web-developer-express-2010-sp1.aspx#VisualStudioDesignersNotWorkingwithCompa">Link here</a> and <a href="http://blogs.msdn.com/b/sqlservercompact/archive/2011/01/12/microsoft-sql-server-compact-4-0-is-available-for-download.aspx">here</a> )</li>
<li>SQL Compact 3.5 wouldn't play nicely with the various items - follow <a href="http://technet.microsoft.com/en-us/library/cc835494.aspx">this link</a> and see the section "Limitations of SQL Server compact" - basically it can't:</li>
<ul><li>"<span style="font-family: 'Segoe UI', Verdana, Arial; font-size: 13px; text-align: left;">support entities with server-generated keys or values when it is used with the Entity Framework</span> ".</li>
</ul></ul><div>There's a lot of other things that SQL server compact can't do - including supporting stored procedures. So that's how we ended up back at SQL Server Express.</div><div><br />
</div><div>I hope this gives you a flavour of the sort of things to consider when looking at data replication on SQL Server.<br />
<br />
You're going to ask why didn't we use SQL Server Merge Replication - that's another story and another post...</div></div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-60912159965579191372012-02-22T23:45:00.000+00:002012-02-22T23:45:23.402+00:00Architecture Note<span style="font-family: Arial, Helvetica, sans-serif;">A short note on architectures for WCF-based solutions - we've found this works for us.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">All classes that are being passed across the wire must be serialisable and each property must be annotated.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The WCF service is nothing more than a thin facade on top of a call to Business Logic. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">In fact it's a one-to-one relationship to the Business Logic calls... The Service layer just exposes the business logic so that it can be used in </span><span style="font-family: Arial, Helvetica, sans-serif;">creating bindings, etc.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Business Logic - as they say, it "does the business" and calls the data access.layer.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Data Access Layer - we're using Repository pattern with Entity Framework.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Throughout, we've using IoC (Ninject) to hook data access repositories into the Business Layer and Business Logic into the Service Layer. This has meant inserting Ninject into the WCF factory pipeline - see <a href="http://blog.solutionist-ltd.com/2012/02/using-ninject-in-wcf-services.html">this post</a>.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">OK, you may ask why create a WCF facade on top of the business logic?</span> <br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Well, doing this lets you create clean classes and "unit" tests for the business logic without bothered about annotations, etc for WCF.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">It also means that the Business Logic layer becomes a re-usable component - where you don't have to include WCF-related annotations and dlls.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
</span>Josephhttp://www.blogger.com/profile/06376242778178384993noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-54680806639114466102012-02-02T00:38:00.000+00:002012-02-02T00:38:03.176+00:00How to get a WPF TextBox to update its ViewModel binding variable<span style="font-family: Arial, Helvetica, sans-serif;">A short post:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Scenario:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">You're using MVVM and have bound a textbox to a string ViewModel property - in TwoWay mode.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">You have a button that is only to be enabled when that string property is not null/empty. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Problem: </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">You type in the textbox, but the button remains firmly disabled until the textbox loses focus.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Only at that point is the string's PropertyChanged event raised.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Solution:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">(Taken from <span style="background-color: white;">http://betaforums.silverlight.net/forums/t/103695.aspx</span> )</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Do the following on the TextBox's TextChanged event:</span>
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"> <span style="color: blue;">void</span> summaryTextBox_TextChanged(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">TextChangedEventArgs</span> e)
{
<span style="color: #2b91af;">TextBox</span> txCtl = (<span style="color: #2b91af;">TextBox</span>)sender;
<span style="color: blue;">if</span> (txCtl != <span style="color: blue;">null</span>)
{
<span style="color: blue;">var</span> be = txCtl.GetBindingExpression(<span style="color: #2b91af;">TextBox</span>.TextProperty);
<span style="color: blue;">if</span> (be != <span style="color: blue;">null</span>)
{
be.UpdateSource();
}
}</span></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"> }
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">This will force the PropertyChanged event to be raised whenever the text is changed - and your button </span><span style="font-family: Arial, Helvetica, sans-serif;">will be enabled as soon as you start typing in the TextBox</span>.<br />
<br />Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-30998130574979583822012-02-01T19:24:00.000+00:002012-02-01T19:25:38.196+00:00More .NET IoC - Using Ninject in WCF Services<div style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="font-family: Arial, Helvetica, sans-serif;">I've seen other postings about this, but thought I'd add my own 2p-worth since I had to struggle a bit to get it working.</span></div>
<div style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="font-family: Arial, Helvetica, sans-serif;">The basic idea is to use Ninject in the WCF pipeline and get WCF use Ninject to create the service. Then you can take advantage of Ninject's IoC to manage dependencies.</span></div>
<div style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<div style="color: black; font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;">I used the base Ninject and the Ninject Web and Wcf extensions - all available via NuGet.</span></div>
<div style="color: black; font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black; font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;">To integrate ninject into the WCF service pipeline, create a "normal" WCF service but add the following to the .svc file</span></div>
<div style="color: black; font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black; font-family: 'Times New Roman';">
</div>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; font-family: Consolas; font-size: 13px;"><span style="color: red;">Factory</span><span style="color: blue;">=</span><span style="color: blue;">"Ninject.Extensions.Wcf.NinjectServiceHostFactory"</span>
</pre>
<br />
<div style="color: black; font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">So, the file would look something like:</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;"><%</span>@ ServiceHost Language="C#" Debug="true" Service="WcfService.GeneralService" </span></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;">CodeBehind="GeneralService.svc.cs" </span></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="color: red;">Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"</span> <span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;">%></span></span></pre>
<br />
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">Then you can inject dependencies into the service as needed as follows:</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;">[Inject]
public IUsersRepository _repository { private get; set; }</span></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-family: Consolas; font-size: 13px;"></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-family: Consolas; font-size: 13px;"><span style="background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-size: small; white-space: normal;">Now we're assuming that you're using a WCF application project - so, to initialise Ninject correctly you need to make changes to the WCF project Global.asax file as follows:</span></pre>
<br />
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
</div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Make Global extend NinjectWcfApplication (from Ninject.Extensions.Wcf)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Implement and override CreateKernel - so the file looks like this:</span></li>
</ol>
<br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> public</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> </span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">class</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> </span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">Global</span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;"> : </span><span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: 13px;">NinjectWcfApplication</span><br />
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"> {</span></pre>
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"> // Other methods omitted for clarity...
protected override Ninject.IKernel CreateKernel()
{
IKernel k = new StandardKernel(new ServiceModule());
return k;
}
}</span></pre>
<br />
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">Now the ServiceModule is a Ninject module that would look something like:</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; font-size: 13px;"><span style="font-family: 'Courier New', Courier, monospace;"> public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<iusersrepository>().To<usersrepository>();
}
}</usersrepository></iusersrepository></span></pre>
<br />
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">Notice that we're binding the IUsersRepository to the UsersRepository implementation.</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">Doing this will enable Ninject to do its magic in the WCF service above where it is injected.</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">When Service is invoked, the Ninject factory will instantiate the class and so be able to use the module bindings to pull in the correct interface implementations.</span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;">Notice that you don't need to change service bindings, etc. </span></div>
<div style="color: black;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-15114000077019347602011-12-29T18:42:00.000+00:002011-12-29T18:43:43.468+00:00Primary Keys in Entity Framework and Sync Framework<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">Hold on - we're going for a
walk on the wild side! It will take a few minutes to read - but it's a
thriller...</span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">This is a summary of what I've discovered after a bit of research - hopefully it will help other developers/architects out.</span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"><br /> As part of a project I'm looking at creating a SQL server replicated
architecture... and need to avoid clashes in the PK. The icing on the cake is that we're using Entity Framework heavily in the project for data access. </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"><b>Exhibit 1 </b>... <a href="http://msdn.microsoft.com/en-us/library/bb726011.aspx">http://msdn.microsoft.com/en-us/library/bb726011.aspx</a><br /><br />
This article gives a few options about choosing a suitable Primary key in replication scenarios:</span>
<span style="font-size: small;"><br />
1. Using a GUID<br />
2. Pk that includes a node ID<br />
3. Natural keys<br /><br />
OK.... starting from the bottom up...</span>
<span style="font-size: small;"><br /></span></div>
<ul>
<li><span style="font-size: small;">
<span style="font-family: Arial,Helvetica,sans-serif;">Natural Keys won't work for our project. Full stop</span></span>
</li>
<li style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">
A PK that includes a Node ID - means adding a column and giving each client a Node ID. Not the end of the world, but...
</span><span style="font-size: small;"> doesn't feel right...</span></li>
<li style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">
GUID... sounds good, or is it?</span>
</li>
</ul>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"><br />
Enter </span>
<span style="font-size: small;"><b>Exhibit 2</b> -<a href="http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/" rel="bookmark" style="color: #c73f17; text-decoration: none;" title="Using a GUID as an EntityKey in Entity
Framework 4"> </a><a href="http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/">http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/</a><br />Yes, it's all true... I tried it and had to hack the EF model XML to include the correct attribute to get it to work. And,
Yes, doing an update loses the change.<br />
Yes, it's a feature and yes, it's not pleasant - it would mean
after every update hacking the XML to find all the relevant GUID PKs and
adding in the
attribute. I'm sure we could automate it by some clever searching and replacing, but it's not right.<br /><br />
Also, Enter </span>
<span style="font-size: small;"><b>Exhibits 3, 4, 5 and 6</b><br /><a href="http://www.eggheadcafe.com/tutorials/sql-server/d662b371-ed27-481c-aee0-ebe7cf2d9fad/why-guids-are-not-a-good-idea-for-sql-server-primary-keys.aspx">http://www.eggheadcafe.com/tutorials/sql-server/d662b371-ed27-481c-aee0-ebe7cf2d9fad/why-guids-are-not-a-good-idea-for-sql-server-primary-keys.aspx</a></span>
<span style="font-size: small;"><br /><a href="http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html">http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html</a></span>
<span style="font-size: small;"><br /><a href="http://www.simple-talk.com/sql/database-administration/the-identity-crisis-in-replication/">http://www.simple-talk.com/sql/database-administration/the-identity-crisis-in-replication/</a></span>
<span style="font-size: small;"><br /><a href="http://sqlblogcasts.com/blogs/martinbell/archive/2009/05/25/GUID-Fragmentation-in-SQL-Server.aspx">http://sqlblogcasts.com/blogs/martinbell/archive/2009/05/25/GUID-Fragmentation-in-SQL-Server.aspx</a></span>
<span style="font-size: small;"><br /><br />
From this set of links you start to see that GUIDs are good, but come with a number of caveats.</span>
<span style="font-size: small;"><br />
Also using newsequentialid() - doesn't necessarily generate sequential
GUIDs - I tried this. If you do a number of inserts close together then
you do get them, but not always. </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">So, you then can potentially have the performance issues.<br />
Also, the space issue is relevant for us - since we're looking to replicate to SQL server compact.<br /><br />
</span>
<span style="font-size: small;"><b>Alternatives?</b><br /><br /><b>First off, </b></span>
<span style="font-size: small;">well we could use a normal ID (int) column and change the seed value for each client.<br />
E.g. The Server has a seed of 10,000000<br />
Client 1 has a seed of 20, 000000,<br />
Client 2 has a seed of 30, 000000 etc<br /><br />
So, each client would be able to make 9,999,999 inserts before a conflict and we'd have a limit of 214(X2) users because we could have negative
numbers as well.</span>
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">Lets just do some maths....</span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">The max value of an int is +/-2,147,483647. </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">If you're really worried about conflicts you could go for using a bigint as the ID column, then you could have something like 9223327036850 clients! The seeds could then be something like 100,000000,
200000000, 300000000, etc so 99,999,999 inserts before a conflict - which should be enough for a
lifetime - e.g. one insert a second would take you 1157 days. 100 inserts a day would
take over 2500 years.</span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"> If you were using the the smaller int then 100 inserts a day would
last over 250 years!<br /><br />
That means changing the seed on each client appropriately.</span>
<span style="font-size: small;"><br />
Now, there are ways of doing this:<br /><a href="http://www.techrepublic.com/blog/datacenter/how-do-i-reseed-a-sql-server-identity-column/406">http://www.techrepublic.com/blog/datacenter/how-do-i-reseed-a-sql-server-identity-column/406</a></span>
<span style="font-size: small;"> but it seems there a some gotchas that you have to be aware of:<br /><a href="http://geekswithblogs.net/argot/archive/2009/10/18/sync-framework-common-practise-of-ado.net.aspx">http://geekswithblogs.net/argot/archive/2009/10/18/sync-framework-common-practise-of-ado.net.aspx</a></span>
<span style="font-size: small;"><br /><br />
Basically, you have to store and remember seed values before/after synchronisation. </span>
<span style="font-size: small;"><br />
You'd keep a list of seed values for each client. So any time you get a
new client the first sync would also download its seed value.<br /><br />
This solution has a certain appeal, because:</span>
<span style="font-size: small;"><br />
a. it leaves the PK alone as a single ID column<br />
b. The replication mechanism takes care of the seeding/reseeding.<br />
c. Entity Framework designer won't throw any wobblies.<br /><br /><b>Next alternative... </b></span>
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">Go back to a compound PK, ID plus a Node ID.<br />
a. Entity Framework should cope with this.<br />
b. Replication mechanism should be a bit simpler.<br />
But... it means infecting the database with the replication details i.e.
the Node ID and artificially creating a more complex PK. So, you can't just go </span><span style="font-size: small;"><span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">select * from Users where ID = 10</span></span>.<br /><br /><b>Another thought....</b></span>
<span style="font-size: small;"><br /><br />This is horrible I think, but has a certain "something" about it!</span>
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">
Leave the PKs alone completely - simple ID column with an int.<br />
Then code for the PK conflicts in the sync framework - as it will detect PK
conflicts. </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">So, we write logic that will do something like:<br />
- determine of the inserted record exists on the server </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">- if not, then
add it (generating a new record/PK) then remove it from the client and </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">
- resync the client to pull down the "new" record but with the updated PK.</span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"><br />
You'd have to write this sort of thing to cover various scenarios and it
may/would be table-specific - but what if we replicating a lot of tables? <br /><br /><br /><b>Summing up...</b></span>
<span style="font-size: small;"><br /><br />We're looking at either the compound PK or the different seed values.</span>
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;">We're going to try some stuff out - probably the different seed values first as that leaves the EF model alone completely - and I'll try and report back how it went. </span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-5800286248350898672011-09-08T15:38:00.000+01:002011-09-08T15:43:44.514+01:00Entity Framework Tip #1 - Using MergeOption to get latest entities<span style="font-family: Arial,Helvetica,sans-serif;">Hopefully this is the first of various Entity Framework tips that I've gleaned along the way.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">They'll serve as reminders for me and if they can help other people, they will have served their purpose.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Ok, what's wrong with this?</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">(We're using STEs because we're throwing things across the network). </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">I was doing some testing and had code that looked like this.</span><br />
<br />
<pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> DBEntities context1 = new DBEntities();
DBEntities context2 = new DBEntities();
Site newSite = new Site();
newSite.SiteName = "QAZ";
context1.Sites.AddObject(newSite);
context1.ApplyChanges("Sites", newSite);
context1.SaveChanges();
Site site2 = context2.Sites.Where(s => s.ID == newSite.ID).FirstOrDefault();
// update the site...
site2.ChangeTracker.ChangeTrackingEnabled = true; // Because they're STEs
site2.SiteName = "QAZ QAZ";
context2.ApplyChanges("Sites", site2);
context2.SaveChanges();
// I thought I'd use the first context to query for the updated site...
var query = context1.Sites.Where(s => s.ID == newSite.ID);</span></span></pre>
<pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> Site site3</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> = query.FirstOrDefault();</span></span></pre>
<br />
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: small;"><i>What's the SiteName of site3?</i></span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
No, it's not "QAZ QAZ" - it's "QAZ"</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<i>Why is that? </i></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
Because the site already exists in context1 - so even though a database query is actually executed, EF will not overwrite what's in context1 because its cache already contains an entity with that EntityKey.</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<i>How to make sure that I actually get the latest values back?</i></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
Set the MergeOption on the objectSet before doing the call - as follows... </div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">context1.Sites.MergeOption = MergeOption.OverwriteChanges;</span></span></pre>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
The default option is AppendOnly which won't update the context if it finds an entity with the</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
same entityKey present.</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
Another tip from the twighlight world of entity framework...<br />
<br />
One thing I've yet to investigate is how delayed execution would affect MergOption settings.<br />
So, if I reset the MergeOption after the query to AppendOnly and then do further queries before finally executing the query - would the different MergeOptions be applied at the right time... hmmm...</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
</div>
Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-32561762158575955232011-06-07T13:03:00.001+01:002011-06-07T13:04:13.276+01:00.NET IoC - part 3 (Spring)<div style="font-family: Arial,Helvetica,sans-serif;">It's been some time, but this is continuing my previous <a href="http://blog.josephbabad.co.uk/2011/01/net-ioc-part-2-structuremap.html">posts </a>about .NET IoC.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">As I'm familiar with Spring from the Java world, I thought I'd transfer that knowledge across to .NET. It turned out to be less painful than I expected.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">I was building a service-based project and used spring on both the client and server sides of the divide. For this post, I'll initially stick to it's use on the client side, but server-side has a very similar set-up. Maybe I'll come to full WCF integration later on.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">For basic IoC you just need the Spring.Core.dll from the distribution - add this as a reference to your project.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">Initially I'm following the KISS principle, so I created a basic application context file - spring.config.xml and put that at the top level of my project.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">Basic format is as follows:</div><code><br />
<?xml version="1.0" encoding="utf-8" ?><br />
<objects xmlns="http://www.springframework.net"><br />
<br />
<object id="Object1"<br />
type="<Assembly name>.namespace.classname1, <assembly name>" singleton="false"></code><br />
<pre style="background: white; color: black; font-family: Consolas; font-size: 13;"><code><</code><span style="color: black; font-family: "Courier New",Courier,monospace;">property name="Property1" ref="Object2" /</span><code>></code>
</pre><code> </object></code><br />
<br />
<code></code><br />
<code><object id="Object2"<br />
type="<Assembly name>.namespace.classname2, <assembly name>" singleton="false"></code> <br />
<code> </object></code><br />
<br />
<code> </objects><br />
</code><br />
<br />
<div style="font-family: Arial,Helvetica,sans-serif;">The <code>singleton="false"</code> will ensure that Spring gives you a new instance every time you request the particular object.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">As a minimum in your code, you'll need to create an application context somewhere.</div><div style="font-family: Arial,Helvetica,sans-serif;">I've put it in a singleton Locator class as follows:</div><code><br />
private static IApplicationContext _context = null;<br />
_context = new XmlApplicationContext("spring-config.xml");<br />
</code><br />
<div style="font-family: Arial,Helvetica,sans-serif;">where spring-config.xml is the name of your config file. This is sitting at the top-level of the project.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">Then you'll want a method to grab hold of an object instance as follows:</div><code><br />
public object getObjectInstance(string name)<br />
{<br />
return _context.GetObject(name);<br />
}<br />
</code><br />
<div style="font-family: Arial,Helvetica,sans-serif;">or, if you need to pass arguments in to the constructor...</div><code><br />
public object getObjectInstance(string name, object[] args)<br />
{ <br />
return _context.GetObject(name, args);<br />
}<br />
</code><br />
<div style="font-family: Arial,Helvetica,sans-serif;">In both cases "name" is the object's ID in the configuration file.</div><div style="font-family: Arial,Helvetica,sans-serif;">Passing arguments in like this is "OK", but can be a pain, since there's no compile time checking - but we're staying simple.</div><div style="font-family: Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: Arial,Helvetica,sans-serif;">At some point you could call:</div><code><br />
Locator.Instance.getObjectInstance("Object1");</code><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">This will:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">create an instance of Object1</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">create an instance of Object2</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">set Property1 on Object1 to be Object2</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">return you a "ready-to-go" instance of Object1.</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"> These are your absolute basics. But hopefully this will put you on the road.</span>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-33629869229038868622011-01-12T23:32:00.002+00:002011-02-15T14:21:14.751+00:00.Net IoC - part 2 (StructureMap)<div style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">It's been</span><span style="font-size: small;"> some time since I've last posted anything up, but I thought I'd put up a bit more about my</span></div><div style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">working with IoC in .NET.</span></div><div style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">In a <a href="http://blog.josephbabad.co.uk/2010/08/net-ioc.html">previous post </a>I mentioned that I'd come across Spring.NET, Unity</span> and StructureMap</div><div style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">I wanted something that I could pick up easily and which focused on IoC. </span><br />
<br />
<span style="font-size: small;"></span><br />
<span style="font-size: small;">Starting to using it fairly simple. </span><br />
<ol><li><span style="font-size: small;">You reference the structuremap dll</span></li>
<li><span style="font-size: small;">Add something looking like this into your code... I wrapped it up in a Singleton to give me more flexibility..</span><span style="font-family: "Courier New",Courier,monospace;"> </span></li>
</ol><span style="font-family: "Courier New",Courier,monospace;">public sealed class Locator</span> <span style="font-family: "Courier New",Courier,monospace;"> {</span> <br />
<span style="font-family: "Courier New",Courier,monospace;"> private static volatile Locator _instance = null;</span> <span style="font-family: "Courier New",Courier,monospace;"> private static object syncRoot = new Object();</span><br />
<pre style="font-family: consolas;"><span style="font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> private static Container objectFactory = null; </span>
<span style="font-family: "Courier New",Courier,monospace;"> private Locator()</span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"> objectFactory = new Container(</span>
<span style="font-family: "Courier New",Courier,monospace;"> x =></span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"> x.For<myservice>().Use<myserviceclient>(); </myserviceclient></myservice></span>
<span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"> x.For<ihelper>().Use<realhelper>();</span></pre><pre style="font-family: consolas;"><span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"> x.For<iinterface1>().Use<implementation1>()</span>
<span style="font-family: "Courier New",Courier,monospace;"> .Setter<myservice>().IsTheDefault();</myservice></span>
<span style="font-family: "Courier New",Courier,monospace;"> });</span><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"></span><span style="color: black; font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span>
<span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"> public static Locator Instance</span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"> get </span>
<span style="font-family: "Courier New",Courier,monospace;"> { </span>
<span style="font-family: "Courier New",Courier,monospace;"> if (_instance == null) </span>
<span style="font-family: "Courier New",Courier,monospace;"> { </span>
<span style="font-family: "Courier New",Courier,monospace;"> lock (syncRoot) </span>
<span style="font-family: "Courier New",Courier,monospace;"> { </span>
<span style="font-family: "Courier New",Courier,monospace;"> if (_instance == null) </span>
<span style="font-family: "Courier New",Courier,monospace;"> _instance = new Locator(); </span>
<span style="font-family: "Courier New",Courier,monospace;"> } </span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span><span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"> return _instance; </span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span>
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> public object getObjectInstance<t>()</t></span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> return objectFactory.GetInstance<t>();</t></span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span>
<span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> public object getObjectInstance<t>(Dictionary<string, object> items)</string, object></t></span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"></span><span style="color: black; font-family: "Courier New",Courier,monospace;"></span>
<span style="font-family: "Courier New",Courier,monospace;"> var args = new ExplicitArguments();</span>
<span style="font-family: "Courier New",Courier,monospace;"> </span>
<span style="font-family: "Courier New",Courier,monospace;"> foreach (var item in items)</span>
<span style="font-family: "Courier New",Courier,monospace;"> {</span>
<span style="font-family: "Courier New",Courier,monospace;"> //args.Set(item);</span>
<span style="font-family: "Courier New",Courier,monospace;"> args.SetArg(item.Key, item.Value);</span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span>
<span style="font-family: "Courier New",Courier,monospace;"> return objectFactory.GetInstance<t>(args);</t></span>
<span style="font-family: "Courier New",Courier,monospace;"> }</span></pre><pre style="font-family: consolas;"><span style="font-family: "Courier New",Courier,monospace;">
</span></pre><span style="font-size: small;"></span><br />
<span style="font-size: small;">In code I'm calling:</span><br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">Locator.Instance.getObjectInstance<type>()</type></span></div><span style="font-size: small;"><br />
</span><br />
<span style="font-size: small;">The second method allow you to pass in constructor parameters.</span><br />
<span style="font-size: small;"><br />
</span><br />
<span style="font-size: small;">All this means I can remove references to StructureMap from my Code and, if need be,</span><br />
<span style="font-size: small;">swap out IoC containters without affecting the rest of the code. In fact, this happened eventually.</span><br />
<br />
<span style="font-size: small;">StructureMap looked a good candidate, the fluent interface is nice and there's no XML if you don't want it! But, I did find the that the lack of decent documentation was an issue.</span><br />
<span style="font-size: small;">There was a lot of information - but scattered around. I didn't want to spent ages hunting stuff down.</span><br />
<br />
<span style="font-size: small;"></span><br />
<span style="font-size: small;">Unity, I'm afraid, seemed over complicated.</span><span style="font-size: small;"> I'm still getting my head round other .Net stuff and I wanted to minimise the amount to learn. </span><br />
<span style="font-size: small;"><br />
</span><br />
<span style="font-size: small;">That left Spring.... which, all being well, I'll cover in part 3.</span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-32479368721704738762010-09-20T17:48:00.000+01:002010-09-20T17:48:54.895+01:00Early Entity Framework thoughts<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">It's been a few weeks since my last post, but I've been reading and working with a couple of good books.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">One of those was O'Reilly's Programming Entity Framework (ISBN </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">9780596807276).</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">It's not an easy read, but, then again, it's not really meant to be. The topic is huge with ramifications across any multi-tier application.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">I'm currently looking at an N-tier app with a combination of </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">WPF, Silverlight and ASP.NET presentation layers, so having the underlying technology and architecture right is critical.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">With that in mind, the sections on WCF RIA and Data services are very helpful and the worked examples are excellent to go through.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Now, behind all this is a niggle along the lines of "I've seen this before"... where? </span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Well, Hibernate's been around Java world some time (Nhibernate more recently for MS) and, before that, you have J2EE's early awkward/abortive (choose your adjective) attempts at ORM using EJB 1 and 2. </span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">EJB3 and Hibernate now provide a data access layer with Spring </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">or EJB3 </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">session beans sitting above that providing declarative transaction management and </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">access control. </span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">We had Data Transfer Objects (DTOs) for passing data across layers.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Moving across to .NET4 we have the DTO equivalent - i.e. POCOs or STEs or RIA Services' own cross-tier mechanism. You also have EF4 providing the ORM and data access, then WCF in it's various forms provides the service/session layer.</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">So, for N-tier apps, I get a feeling of it being a case of "Hello Microsoft, welcome to my world!".</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">It's early days and I'll see how this all goes in MS-land. Having done some prototyping, I have to say is that the MS tooling goes a good way to smoothing out a lot of bumps in the road. </span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">I'm still waiting for Netbeans/Eclipse/MyEclipse to get to the level of Visual Studio tooling - especially when developing UIs. </span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">See you back here soon.</span><br />
<h6 class="western"> </h6>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-66567311638901922562010-08-10T18:56:00.001+01:002010-08-10T19:48:07.926+01:00Quartz.NET <span class="Apple-style-span" style="font-family: arial;">I haven't got round to trying Spring.NET yet, but had a play with another Java-to-.NET port: Quartz.NET.</span><br />
<div><span class="Apple-style-span" style="font-family: arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: arial;">I'm sure that there are other posts/tutorials about how to get it working, but I'll add in my twopennyworth as a step-by-step account of what I did.</span></div><div><span class="Apple-style-span" style="font-family: arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: arial;">1. Downloaded latest version of Quartz.NET - 1.0.2</span></div><div><span class="Apple-style-span" style="font-family: arial;"></span></div><div><span class="Apple-style-span" style="font-family: arial;">2. Using VS2010, I created a Web Project and added references to the Quartz and Common.Logging dll's that are in the bin directory</span></div><div><span class="Apple-style-span" style="font-family: arial;">3. For good measure I also added a reference to the log4net dll - I would be using this in the Quartz job.</span></div><div><span class="Apple-style-span" style="font-family: arial;">4. For log4net config, I kept this separate from the application and placed a log4net.config file in project. I then referenced this in Global.asax as follows:</span></div><div><span class="Apple-style-span" style="font-family: arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><span class="Apple-style-span" style="font-size: small;"> log4net.Config.DOMConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "log4net.config"));</span></span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br />
</span></div><div><span class="Apple-style-span" style="font-family: arial;">My log4net config file looked like:</span><br />
<span class="Apple-style-span" style="font-family: arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: arial;"></span><br />
<span class="Apple-style-span" style="font-family: arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: arial;"><pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender"/>
</root>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\Logfile.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Composite"/>
<datePattern value="yyyyMMdd"/>
<maxSizeRollBackups value="10" />
<maximumFileSize value="1000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t]%-5p %c [%x] - %m%n" />
</layout>
</appender>
</log4net></code></pre></span><br />
<span class="Apple-style-span" style="font-family: arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: arial;">5. Ran the database script (for SQL server) to create the relevant tables.</span></div><div><span class="Apple-style-span" style="font-family: arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: arial;">6. Updated the Web. Config file as follows:</span><br />
<span class="Apple-style-span" style="font-family: arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: arial;"></span><br />
<span class="Apple-style-span" style="font-family: arial;"></span><br />
<span class="Apple-style-span" style="font-family: arial;"><div style="font-size: small;"></div><pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <configSections>
<div style="font-size: small;"> <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" /></div><div style="font-size: small;"> </configSections></div></code>
<div style="font-size: small;"></div></pre><br />
<br />
<div style="font-size: small;"><br />
</div></span><br />
<span class="Apple-style-span" style="font-family: arial;"></span><br />
<span class="Apple-style-span" style="font-family: arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: arial;"><pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <quartz>
<add key="quartz.scheduler.instanceName" value="CommerceScheduler" />
<!-- Configure Thread Pool -->
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<!-- Configure Job Store -->
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<!--<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />-->
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.dataSource" value="default" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.clustered" value="true" />
<add key="quartz.jobStore.lockHandler.type" value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.dataSource.default.connectionString" value="Data Source=Server_Name;Initial Catalog=quartz;Integrated Security=True" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
<add key="quartz.jobStore.useProperties" value="true" />
</quartz></code></pre></span><span class="Apple-style-span" style="font-family: arial;"><br />
<br />
</span></div><div><span class="Apple-style-span" style="font-family: arial;"></span><br />
<span class="Apple-style-span" style="font-family: arial;"><div>7. Created a test job:</div><div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">public class QuartzJob1 : IJob</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">{</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> protected static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); </span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> void IJob.Execute(JobExecutionContext context)</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> {</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> log.Debug("QuartzJob1 run");</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> }</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">}</span></span></div></div><div><br />
</div><div>8. For testing purposes created a class with the following static method.</div><div><br />
</div><div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">public static void InitQuartz()</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">{</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> // construct a scheduler factory</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> ISchedulerFactory schedFact = new StdSchedulerFactory();</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> // get a scheduler</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> IScheduler sched = schedFact.GetScheduler();</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> sched.Start();</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> // construct job info</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> JobDetail jobDetail = new JobDetail("myJob", null, typeof(QuartzJob1));</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> // fire every hour</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> Trigger trigger = TriggerUtils.MakeMinutelyTrigger();</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> // start on the next even hour</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> trigger.StartTimeUtc = TriggerUtils.GetNextGivenMinuteDate(DateTime.UtcNow, 1);</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> trigger.Name = "myTrigger";</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> sched.ScheduleJob(jobDetail, trigger);</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">}</span></span></div></div><div><br />
</div><div>9. Global.asax added a call to InitQuartz()</div><div><br />
</div><div>10. Ran the application.</div><div><br />
</div><div>You should see a log message being written out every minute.</div><div>And you should see entries in the </div><div>QRTZ_SIMPLE_TRIGGERS and QRTZ_FIRED_TRIGGERS tables.</div><div><br />
</div><div><br />
</div><div><br />
</div></span></div><div><span class="Apple-style-span" style="font-family: arial;"><br />
</span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-25727049579792651312010-08-06T14:30:00.006+01:002010-08-06T14:44:36.920+01:00RIA Services and ASP.NET<span class="Apple-style-span" style="font-family:arial;">I've been looking at WCF RIA services for a new project - and looking at seeing if I can use the DomainService on an ASP.NET page directly. </span><div><span class="Apple-style-span" style="font-family:arial;"><br /></span><div><span class="Apple-style-span" style="font-family:arial;">This gets you to a half-way house situation </span><span class="Apple-style-span" style=" ;font-family:arial;">where you have your middle-tier, but don't have to learn Silverlight just yet. It's not immediately obvious where to start, but you need to get hold of the RIA services toolkit (for SL4... I'm working with VS2010) - which then gives you a DomainDataSource available for use on .aspx pages.</span></div></div><div><span class="Apple-style-span" style=" ;font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">So.... created my DomainService with a couple of related entities.</span></div><div><span class="Apple-style-span" style="font-family:arial;">pulled in a couple of DomainDataSources for the master and detail queries and hooked up </span><span class="Apple-style-span" style=" ;font-family:arial;">a grid for the master query and DetailView for the detail.</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">The basic concept worked fine!</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">But.. then I tried to enable paging and sorting in the master and detail view and got this error</span></div><div><span class="Apple-style-span" style="font-family:arial;"><h4><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-weight: normal;"></span></span></i></h4><blockquote><h4><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-weight: normal;">The method ‘Skip’ is only supported for sorted input in LINQ to Entities. The method ‘OrderBy’ must be called before the method ‘Skip’.</span></span></i></h4><b><span class="Apple-style-span" style="font-size:medium;">Description: </span></b><span class="Apple-style-span" style="font-size:medium;">An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.<br /></span><b><span class="Apple-style-span" style="font-size:medium;">Exception Details: </span></b><span class="Apple-style-span" style="font-size:medium;">System.NotSupportedException: The method ‘Skip’ is only supported for sorted input in LINQ to Entities. The method ‘OrderBy’ must be called before the method ‘Skip’. </span></blockquote>Hmmm....<br /></span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">It turns out (thanks to this <a href="http://msdnrss.thecoderblogs.com/2010/05/22/using-domain-service-with-aspnet-dynamic-data/">link</a>) that you need to add some default ordering to your query methods in the DomainService. This enforces the ordering before any other modifier.</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com1tag:blogger.com,1999:blog-6406442277861689963.post-89628655180177963082010-08-04T22:52:00.000+01:002010-08-04T23:07:07.770+01:00Training<span class="Apple-style-span" style="font-family:arial;">Running an ASP.NET training course recently got me thinking about the range of skills someone needs nowadays working in IT. </span><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">The students came from a wide range of backgrounds - some with more or less development experience, but the range of topics we were covering on was huge:</span></div><div><ul><li><span class="Apple-style-span" style="font-family:arial;">HTML</span></li><li><span class="Apple-style-span" style="font-family:arial;">Javascript</span></li><li><span class="Apple-style-span" style="font-family:arial;">C#</span></li><li><span class="Apple-style-span" style="font-family:arial;">OO concepts</span></li><li><span class="Apple-style-span" style="font-family:arial;">XML</span></li><li><span class="Apple-style-span" style="font-family:arial;">Security</span></li><li><span class="Apple-style-span" style="font-family:arial;">Database access</span></li><li><span class="Apple-style-span" style="font-family:arial;">Visual Studio IDE (a course in itself!)</span></li></ul><div><span class="Apple-style-span" style="font-family:arial;">... and we're not even talking about particularly complex sites.</span></div></div><div><span class="Apple-style-span" style="font-family:arial;">If you are talking about complex enterprise applications, then you're into services (of varying kinds), AJAX, async messaging, enterprise integration, design patterns, various competing Microsoft and Java/J2EE technologies, etc, etc</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">I've picked this up over many years in the industry - these students are faced with a bewildering array of information to absorb at the outset. Unfortunately, all too often, potential employers want to see the "finished" article - but it doesn't happen overnight.</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">I wish them well on their chosen career path - if they appreciate that being in IT means being willing to look at new ideas and continue learning, then they're a good part of the way there to appreciating what IT is as a profession.</span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0tag:blogger.com,1999:blog-6406442277861689963.post-770964857035582532010-08-04T22:31:00.000+01:002010-08-04T22:38:41.111+01:00.NET IoC<span class="Apple-style-span" style="font-family:arial;"><div><span class="Apple-style-span" style="font-family:arial;">Blogging is a new departure for me, but now I've started my own company (<a href="http://www.solutionist-ltd.com">Solutionist</a>) - it seemed like a good </span>time to start... so here goes...</div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div>I've been working a lot with .NET technologies lately and have been trying to pull across my<br /></span><div><span class="Apple-style-span" style="font-family:arial;">existing Java/J2EE knowledge as a frame of reference. </span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">Something that was sorely missing was Dependency Injection - I'd become fairly hooked on Spring for that and was really missing it in Microsoft World. So, finding Spring.NET and Microsoft's own Unity framework has come as a bit of a relief. Now it's just a case of seeing which one "fits" better.</span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;">Hopefully, over the next few days as I try them both out, I'll write it up.</span></div>Josephhttp://www.blogger.com/profile/15654104388244768914noreply@blogger.com0