#Sponsors       Minimize  
Locations of visitors to this page

             
    #MCP       Minimize  


             
    #CISS.SideMenu       Minimize  

             
    #Search_Blog       Minimize  

             
    #FeedJIT       Minimize  

             
    Sprouting Synapses       Minimize  

             
    {Blog2}       Minimize  
Where I post whatever is crossing my mind...

Once in a while I need a ReadOnly dictionary…except that I couldn’t remember where I had written it last time.

So here is one slapped together just now for this current project I’m working on:

Read More »

I’m working on a multi-threaded solution for dequeueing  prioritized queue and was looking around for an answer as to how many threads I should spawn.

An interesting part of the answer is that there is a max:

Often I see people asking why they can't create more than around 2000 threads in a process. The reason is not that there is any particular limit inherent in Windows. Rather, the programmer failed to take into account the amount of address space each thread uses.

Why does it give up at around 2000?
Because the default stack size assigned by the linker is 1MB, and 2000 stacks times 1MB per stack equals around 2GB, which is how much address space is available to user-mode programs.

Link: http://blogs.msdn.com/oldnewthing/archive/2005/07/29/444912.aspx

Then again:

STFW
http://www.developerweb.net/forum/archive/index.php/t-3030.html
Anyway, I believe it was Raymond Chen who said if you're caring about the maximum number of threads per process you're probably doing something wrong.

And finally:

the problem with this question is one of variant load. if you have threads that are , lets say crawling websites for example, you will have a dynamic load for each thread. In that case a static pool is erroneous. you'll want to monitor your threads performance and watch for attrition across the board. That uses resources so you will be sacrificing a few threads in the process, but it will keep the instance from crashing.
but the easy answer to your question is 500 :)

 

Which I guess sums it up…variable threads is the way to go, based on metrics…a bit harder than I thought.  I suddenly like that easy 500 answer!

 

Links:

powered by metaPost

I saw this happen first with NDoc, and today I came across another fantastic example of why open source projects financed by the mythical community freeloaders are…a fallacy.

Pegasus mail is not a small insignificant product…it’s been around for ever. For it to go down is due to lack of financing is …sad.
But today, going by the official website, I came across the following open letter:

An open letter to the Pegasus Mail and Mercury user community

For over nineteen years, I have been writing and maintaining Pegasus Mail and Mercury; indeed, they have become such a core part of what I am that I sometimes have trouble distinguishing the boundary between them and me. I would like to believe that during those nineteen years, I have provided something that people have enjoyed using and which has enriched their lives.

Nineteen years is a long time though, and in that time the Internet has changed dramatically - it has gone from being something that most people hadn't even heard of when I began, to being so pervasive that most people now can't imagine a world without it. As the Internet has grown and changed, so have the attitudes of the community of people who use it: phenomena such as YouTube and FaceBook have changed the way people interact with each other, but have also engendered a common expectation that everything should be free.

Now, as someone who has always given his software away to the maximum extent possible, I'm clearly not against the idea of things being free, but I also believe it's not unreasonable to expect that things requiring as much work, investment and ongoing effort as Pegasus Mail and Mercury should be able to generate a modest living income. Unfortunately, for the last three years they simply have not done so, where prior to that they did.

We're not talking about huge numbers here - all it would take to secure the indefinite existence and support of both programs would be for a thousand people to commit to a donation of US$50 each year. With the size of the user community, this doesn't seem like a very big ask to me, but for the last three years, unfortunately, we haven't come anywhere near these numbers.

We are reaching a point where I simply will no longer be able to afford to develop Pegasus Mail and Mercury any more - my resources, never very large to begin with, have now dwindled to the point where I simply can't continue draining them. I have tried a variety of "business models", from selling manuals to licensing Mercury, but so far I clearly haven't found one that will work in this "new age" of the Internet.

I know my user community, and consider myself very lucky to have so many wonderful and caring people using my work; knowing my community as I do, I also know that many people who read this will immediately want to make a donation of some kind, or find some way of paying something, and I truly appreciate that thought. The problem, though, is that six months down the track, I would find myself in the same difficult position as I do now - a rush of donations would only be a brief reprieve unless it could be sustained. What we need is something that will produce a modest but reliable ongoing annual income.

In the end, the decision about whether or not Pegasus Mail and Mercury should continue to their twentieth year and beyond is up to you, the people who use them. Are there a thousand of you who feel that $50 each year is a fair price to pay for having these pieces of Internet history live on? If you count yourself amongst that thousand, and feel that this is an ongoing commitment you would be willing to make, send a short message with your name and e-mail address to TheThousand@pmail.gen.nz. In a few weeks time, I'll do a head count and see how many people there are. Think of it as a kind of "vote for the future".

I would really like to see my "babies" make it out of their teens and into their twenties - as long as we can find a way of providing a basic level of ongoing financial support for them and me, I am willing to keep working on them and making them freely available. It's up to you.

Cheers!

-- David Harris --
June 20th 2009.

 

Sad. But instructive.

powered by metaPost

I’m working on a messaging thingy and needed to specify the SMTP host/port/user/pwd settings somewhere in the config file.

I could role my own – or consider using what’s already built into the system.

Turns out that for the framework’s .NET email system has a config setting as follows:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<mailSettings>

<smtp deliveryMethod="network">
<network
host="localhost"
port="25"
userName ="foo"
password ="fii"
defaultCredentials="false"
/>
</smtp>
</mailSettings>
</system.net>
</configuration>

Which you can easily pick up as follows:

const string C_SMTP_XPATH =
"system.net/mailSettings/smtp";
static void Main(string[] args)
{
pSection smtpSec = (SmtpSection)
ConfigurationManager.GetSection(
C_SMTP_XPATH);

sole.WriteLine(smtpSec.Network.Host);
sole.WriteLine(smtpSec.Network.Port);
sole.WriteLine(smtpSec.Network.UserName);
sole.WriteLine(smtpSec.Network.Password);
sole.WriteLine(smtpSec.Network.TargetName);
sole.WriteLine(smtpSec.Network.DefaultCredentials);

 

Which gives the expected results

localhost
25
foo
fii

False

 

Then again…I decided to offer both options – roll my own, as well as offer the above solution.

powered by metaPost

I’m tired of Type.GetType() bitchin’ at me that it can’t find a Type…

Note:
If the assembly name is not specified in the typeName string, Type.GetType() will search inside this assembly only; otherwise, it tries to find one in the caller assembly and then the system assembly (mscorlib.dll).

But…the Assembly name has to be A FQN... which I often forget putting on.

 

So…this time I decided to try a dumb hack to sort that out:

if (deliveryServiceTypeName.IndexOf(
"Version=",
StringComparison.InvariantCultureIgnoreCase) == -1)
{
deliveryServiceTypeName +=
", Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
}

Type deliveryServiceType =
Type.GetType(deliveryServiceTypeName);

Dumb…but very useful!

 

Links:

http://blogs.msdn.com/suzcook/archive/2003/05/30/using-type-gettype-typename.aspx

http://blogs.msdn.com/haibo_luo/archive/2005/08/21/454213.aspx

powered by metaPost

I just did a test to see how fast WCF was across a boundary, using tcp binding. No comparison at 1/12000th the speed….

 

The ServiceContract was:

[ServiceContract]
public interface IWCFServiceContract
{

[OperationContract]
string GetData(int value);

[OperationContract]
int Add(int a, int b);
}

implemented as:

public class WCFServiceImplementation : IWCFServiceContract {
#region IWCFServiceContract Members
public string GetData(int value) {
string line = string.Format(
"{0}: Hello! {1}",
DateTime.Now, value);
return line;
}

#endregion

#region IWCFServiceContract Members


public int Add(int a, int b) {
return a + b;
}

#endregion
}

 

I then called the Add method a whole bunch of times, both in Memory, and over the wire:

static void Main(string[] args)
{
using (ServiceReference1.WCFServiceContractClient happyClient =
new ServiceReference1.WCFServiceContractClient())
{
int iMax = 10000;
DateTime start;
TimeSpan elapsed;

start = DateTime.Now;
for (int i = 0; i < iMax; i++)
{
LocalAdd(i, i);
}
elapsed = DateTime.Now.Subtract(start);
Console.WriteLine("InProc: " + elapsed.TotalMilliseconds);

for (int i = 0; i < iMax; i++)
{
happyClient.Add(i, i);
}
elapsed = DateTime.Now.Subtract(start);
Console.WriteLine("Over TCP: " + elapsed.TotalMilliseconds);
Console.ReadLine();
}
}

static int LocalAdd(int a, int b)
{
return a + b;
}

 

And Got the following output:

InProc: 1.0001
Over TCP: 11429.6538

As I said…no comparison  … crossing boundaries is expensive

powered by metaPost

“... a jury is made up of people who are too stupid to get out of jury duty.”

Links:

This reinforces the fact that

http://government.zdnet.com/?p=4994

powered by metaPost

I just ran into a WCF issue that drove me nuts looking for the answer.

Basically, I was doing what I’ve done many times before without error (namely using Visual Studio’s “Add Service Reference…” tool to build the client side proxy to the server’s exposed ServiceContract, but it kept on bailing at the very end, saying that it could not generate the code.

 

What I was doing was:

image

which brings up:

image

Which if you press browse, finds the services in the solution from which I pick one…and then click Advanced to finesse it a bit…such as decide if I want to also provide Async method stubs (I always do), and how to represent arrays:

image

The point is that I’ve done this a thousand times, and everything worked perfectly.

And then this time, I get…

 

image

And when I look at the code that was supposed to be generated, I get… nothing:

image

 

So what happened?

 

The Solution

Turns out that after looking at the error messages, I see references to an assembly called Mimi…an assembly I don’t have, never heard of before, nor specifically care about… What’s going on?

It turns out that the import tool is dumb (-ish).

What’s going on is that this Mimi assembly (which I don’t have) is a reference of the assembly HsPluginSdk which I do have in the bin of the assembly I am scanning from.

What’s not obvious is that we’re talking here about the bin directory of the assembly I am scanning from, not the assembly  (not the the assembly I am scanning…)

By scanning all assemblies, it’s analyzing the HsPluginSdk , not finding Mimi, and giving up…even though it has nothing to do with the price of cheese.

The solution is to be more specific for once:

image

That finally gets it to spit out the right code:

 

image

Whew! Took me quite a while to stop rushing, look at the error message, and sort things out…

powered by metaPost

I’m creating a Message Client assembly that communicates with a server via WCF.

 

One thing I noticed was if the client config doesn’t have any configuration set up to define the end point, it causes an exception when building the client.

My first solution was to try/catch it, and if it failed (ie had no endpoint configuration defined) catch and build it using hard-coded specs:

try
{
_ServerClient =
new X.Messaging.Client.Services.MessagingServiceClient();
}
catch(System.Exception e)
{
string endPointAddress = "http://{MachineName}/MessagingService.svc";

endPointAddress =
endPointAddress.Replace("{MachineName}", "localhost:63552");

System.ServiceModel.EndpointAddress endPoint
= new System.ServiceModel.EndpointAddress(endPointAddress);

System.ServiceModel.Channels.Binding binding =
new System.ServiceModel.WSHttpBinding();

_ServerClient =
new X.Messaging.Client.Services.MessagingServiceClient(
binding,
endPoint);
}

 

But a failure could be for a whole bunch of reasons… so I wanted to a way to scan a bit more and find out if there was configuration specified – or whether it simply was poorly configured…

 

AlexDrenea suggested the idea of scanning the config file, and I fleshed it out as follows:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Configuration;

namespace XAct.Study.WCF.CheckForEndpoints
{
class Program
{
static void Main(string[] args)
{
//WSHttpBinding_IMessagingService
bool serviceDefined =
ServiceDefined("WSHttpBinding_IMessagingService");
}

static bool ServiceDefined(string serviceName)
{
ChannelEndpointElement endpointConfigElement;
return ServiceDefined(serviceName, out endpointConfigElement);
}


static bool ServiceDefined(string serviceName,
out ChannelEndpointElement endpointConfigElement)
{

if (string.IsNullOrEmpty(serviceName))
{
throw new System.ArgumentNullException("serviceName");
}
endpointConfigElement = null;

Configuration configuration =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None
);

ConfigurationSectionGroup configurationSectionGroup =
configuration.GetSectionGroup("system.serviceModel");

if (configurationSectionGroup == null)
{
return false;
}

ClientSection clientSection =
configurationSectionGroup.Sections["client"]
as ClientSection;


if (clientSection == null)
{
return false;
}

//clientSection.Endpoints[serviceName] does not work because
//key is not what you would expect...not name, address, but
//something like:
//"contractType:ServiceReference1.IMessagingService;
// name:WSHttpBinding_IMessagingService"

foreach (ChannelEndpointElement ep in clientSection.Endpoints)
{
if (ep.Name == serviceName)
{
endpointConfigElement = ep;
break;
}
}
if (endpointConfigElement == null)
{
return false;
}
return true;

}

public static bool DoesEndpointHaveBehavior(
ChannelEndpointElement endpointConfiguration)
{
EndpointBehaviorElement foundBehaviorElement;
return DoesEndpointHaveBehavior(
endpointConfiguration,
out foundBehaviorElement);
}

public static bool DoesEndpointHaveBehavior(
ChannelEndpointElement endpointConfiguration,
out EndpointBehaviorElement foundBehaviorElement)
{
string behaviourConfigurationName =
endpointConfiguration.BehaviorConfiguration;

foundBehaviorElement = null;
if (string.IsNullOrEmpty(behaviourConfigurationName))
{
return true;
}

Configuration configuration =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None
);

ConfigurationSectionGroup configurationSectionGroup =
configuration.GetSectionGroup("system.serviceModel");

if (configurationSectionGroup == null)
{
return false;
}

BehaviorsSection behaviorSection =
configurationSectionGroup.Sections["behaviors"]
as BehaviorsSection;


foreach (EndpointBehaviorElement behaviorElement in
behaviorSection.EndpointBehaviors)
{
if (behaviorElement.Name == behaviourConfigurationName)
{
foundBehaviorElement = behaviorElement;
break;
}
}

if (foundBehaviorElement == null)
{
return false;
}

return true;

}

}//Class:End
}

 

The above code should give options on how to prompt the end programmer on how to set up the config file, etc.

powered by metaPost

This one drove me nuts when I was on a tight deadline…

You add a new WCF  *.svc page to one assembly, wire it up, go to another assembly, press Discover, find it, click it, and boom...you get an error. What's going on?!?

First, the error message is referring to the Service attribute in the *.svc page:

<%@ ServiceHost 
Language="C#"
Debug="true"
Service="X.Messaging.Services.ReportingService"
CodeBehind="ReportingService.svc.cs" %>

which points back to the config file’s service entry, where it’s looking for a service element of the same name:

<system.serviceModel>
<services>
<service name="X.Messaging.Services.ReportingService"
behaviorConfiguration="X.Messaging.Services.ReportingServiceBehavior">
<!-- Service Endpoints -->
<endpoint address=""
binding="wsHttpBinding"
contract="X.Messaging.Services.IReportingService">
<!-- CHANGE BEFORE DEPLOYING: -->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>


<behaviors>
<serviceBehaviors>
<behavior name="X.Messaging.Services.ReportingServiceBehavior">
<!-- CHANGE BEFORE DEPLOYING: -->
<serviceMetadata httpGetEnabled="true"/>
<!-- CHANGE BEFORE DEPLOYING: -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>

</system.serviceModel>
configuration>

which is pointing to a specific behavior element (in this case X.Messaging.Services.ReportingServiceBehavior).

 

The point is…all that looks right…and yet….it still blows up!

Why?

 

Turns out there the reason (in this case at least) is dumb…

I wrote the pages, edited them, saved them even…then went to referring assembly and tried to add this WCF service…

What did I forget to do? I forgot to compile the assembly containing the service. So when it’s Discovering, it’s discovering the *.svc page – but its pointing to stuff in an assembly that doesn’t yet have code within it.

Moral of the story: Compile the service assembly first, then Service Bind to it…

 

Other ideas

If that doesn’t solve the problem, other possible options to consider are the following:

http://blogs.msdn.com/chrsmith/archive/2006/08/10/WCF-service-nesting-in-IIS.aspx

http://www.thejoyofcode.com/WCF_The_type_provided_as_the_Service_attribute_could_not_be_found.aspx

And I don’t think this is right, but i may be wrong.

powered by metaPost

imageThe Russian Tsar Bomba, was the culmination of a series of high-yield thermonuclear weapons designed by the USSR and USA during the 1950s.

Detonating on October 30, 1961, it is still the single most physically powerful device ever utilized throughout the history of humanity.

Its 100 Megaton potential yield was artificially *restrained* to 50Megatons (by contrast, the largest weapon ever produced by the US, the now-decommissioned B41, had a predicted maximum yield of 25 Mt, and was never detonated anyway).

It was detonated 4 miles from the ground.
The resulting fireball touched the ground, reached nearly as high as the altitude of the release plane (10.5 miles up).
The subsequent mushroom cloud was about 64 kilometres high (nearly seven times higher than Mount Everest) and 40 kilometres wide.
The heat from the explosion could have caused third degree burns 100 km away.
The fireball could be seen, and blast damage occurred up to 1,000 kilometres away.
The seismic shock created by the detonation was measurable even on its third passage around the Earth.
Its Richter magnitude was about 5 to 5.25 -- and that even after it was detonated in the air rather than underground (ie: most of the energy was not converted to seismic waves).

What were they thinking?!?
Such large yield bombs were designed because:

The nuclear bombs of the day were so large and heavy that they could only be delivered by relatively slow strategic bombers, and it was therefore feared that only a few would reach their intended drop zone.  In addition both sides lacked precise knowledge -- prior to spy satellites -- of the location of enemy targets.  Combined with the fact that that large bombs dropped without benefit of the inertial navigation systems that were later developed, could easily miss its intended target by six kilometers or more. For all these reasons, the bombs were designed to destroy everything within 5 to 10 kilometres from their detonation point.

 

But we’re all safe now…cough…
Note that subsequent nuclear weapon design focuses primarily on increased accuracy, miniaturization, and safety:
The standard practice for many years has been to employ multiple smaller warheads (MIRVs) to "carpet" an area: this increases the destruction power while reducing the fallout.

 

Link:

http://en.wikipedia.org/wiki/Tsar_bomba

powered by metaPost
By Sky Sigal

Hot peppers are actually NOT corrosive

There is an understandable belief that hot peppers would be corrosive. They give such a burning sensation that people are led to think that they would have the same effect as sulfuric acid or, at the other end of the pH scale, caustic soda.

Actually, the ONLY significant effect of capsaicin is directly stimulating nerve terminations that make you feel pain (which, in turn, induces your body to produce pleasurable endorphins to counteract, which is apparently why [some] people like hot dishes).

Scientists have made experiments directly instilling hot pepper extracts into the stomach using a sound and there was NO effect. However, prepared sauces such as Tabasco did irritate the mucous lining because of the vinegar contained in it, since vinegar *is* a known gastric irritant.

Likewise, I remember seeing promotional materials from the makers of Tabasco years ago, saying that they have to let the sauce age in casks put together without nails or other metal parts, because they wouldn't be able to withstand the corrosion. Actually, that corrosion would likely come from the salt contained in the sauce - which given the special fossil salt used in Tabasco, could possibly have even stronger electrolytic properties than common table salt.”

powered by metaPost

Programming is 10% science, 20% ingenuity, and 70% getting the ingenuity to work with the science.

 

Others:

Debugging: Removing the needles from the haystack.

powered by metaPost

NVIDIA’s Tegra 650 (the “Computer on a Chip”) features:

  • All-day media processing, for 130 hours audio, 30 hours HD video playback
  • HD image processing for advanced digital still camera and HD camcorder functions
  • Optimized hardware support for Web 2.0 applications for a true desktop-class internet experience
  • Display support for 1080p HDMI, WSXGA+ LCD and CRT, and NTSC/PAL TV-Out   (1680×1050 pixels 16:10 aspect ratio.)
  • Direct support for WiFi, disk drives, keyboard, mouse, and other peripherals
  • A complete Board Support Package (BSP) to enable fast times to market for Windows Mobile-based designs

 

http://www.nvidia.com/object/io_1212391368499.html

powered by metaPost

Silverlight 3 will be launched July 10.

Windows 7 will be released to RTM in “second half of July”.

Hopefully that ensures that Silverlight 3 is the version that will get the market penetration we have all been waiting for.

Links:

Silverlight 3 to launch July 10 All about Microsoft ZDNet.com

http://blogs.zdnet.com/Bott/?p=1021&tag=nl.e539

http://riastats.com (currently 28% – up a couple of points from last month)…

powered by metaPost

I’ve just talked about AutoMapper… might as well combine it with another technique – static operators.

With the two concepts, one can map from DTO to BO and back again with seamless grace (although not free):

using System;

namespace QuickSharp
{
class Program
{
static void Main()
{
try
{
Bar b = new Bar();
b.First = "John";
b.Last = "Smith";
Foo f = (Foo)b;

Bar b2 = (Bar)f;

Console.WriteLine(f.FullName);
Console.WriteLine(b2.Last);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}

class Bar {
public string First;
public string Last;

public static explicit operator Foo (Bar bar){
Foo result = new Foo();
result.FullName = bar.First + " " + bar.Last;
return result;
}
}

class Foo {
public string FullName;


public static explicit operator Bar(Foo foo) {
string[] parts = foo.FullName.Split(' ');
Bar result = new Bar();
result.First = parts[0];
result.Last = parts[1];
return result;
}

}
}

 

PS: Note the Source type provides the operator…

 

Links:

http://msdn.microsoft.com/en-us/library/xhbhezf4(VS.80).aspx

powered by metaPost

I’m investigating AutoMapper this morning, in order to decide whether it can be used to Project (versus Map) the ORM created objects, into other objects...

Having run the following tests, it looks very promising…

Read More »

For LLBLGen I needed a Type Converter from an Enum to a Byte – and back.

Actually – I needed several converters, one for each enum I was considering.

The easiest solution I thought was to use a Generic TypeConverter. Surprisingly, the NET Framework doesn’t have one.

Which makes sort of sense, because the ConvertTo method’s wiring is a moster that doesn’t always work. Actually, it appears to never work when I need it.

So I first wrote my own ConvertTo methods…then wrapped it with a TypeConverter:

Read More »

You forget these things…

I’ve just installed Windows 7 last week, and yesterday had trouble connecting to SQL Server Express from Visual Studio.

It’s always the same old thing really… you forget it every time.

 

Have to open the Configuration Manager:

image

In order to turn on TCP/IP access to SQL Server:

image

Which gives you the warning that you have to restart the service:

image

Which you do…

image

And everything becomes right as rain…

 

 

Slightly Off-topic: If working with named pipes, this link may help:
http://blogs.msdn.com/sql_protocols/archive/2007/03/31/named-pipes-provider-error-40-could-not-open-a-connection-to-sql-server.aspx

powered by metaPost

Right, now we have that out of the way this post is actually about Dependency Injection; so what is DI? Well, normally, when an object has to consume a service, it is that object's responsibility to "know" how to gain access to that service. However, sometimes that is not always desirable; take for example, the instance where you wish to use a different service in test and in production, how will you handle that without code changes? Well, the  answer is the DI pattern.

In the DI pattern the object consuming the service merely provides a property into which the required service is "injected" at runtime. In the example below, you can see that two services are created (each implementing the IService interface) and the required Service (specified in a config file) is "injected" into the Consumer at runtime.

 

 

using System;
using System.Configuration;
using System.Reflection;

namespace QuickSharp.DI
{
class Program
{
static void Main()
{
ServiceConsumer serviceConsumer
= new ServiceConsumer();

string serviceName =
ConfigurationSettings.AppSettings["ServiceName"];

if (string.IsNullOrEmpty(serviceName)){
serviceName = "QuickSharp.DI.SomeServiceA";
}
Type serviceType = Type.GetType(serviceName);

ConstructorInfo ci =
serviceType.GetConstructor(
Type.EmptyTypes);

ISomeService instantiatedService =
ci.Invoke(null) as ISomeService;

//Now that service is created,
//inject it into the Consumer:
((ISomeServiceConsumer)serviceConsumer).Service =
instantiatedService;


//And consume it:
serviceConsumer.ConsumeService();
Console.ReadLine();
}
}
//Interface of Service
public interface ISomeService {
void DoSomething();
}
interface ISomeServiceConsumer {
ISomeService Service {get;set;}
}

public class SomeServiceA : ISomeService {
public void DoSomething(){
Console.WriteLine("ServiceA says Hi...");
}
}

public class SomeServiceB : ISomeService {
public void DoSomething(){
Console.WriteLine("ServiceB says Hi...");
}
}


public class ServiceConsumer : ISomeServiceConsumer {

ISomeService ISomeServiceConsumer.Service {
get{return _Service;}
set{_Service = value;}
}
ISomeService _Service;

public ServiceConsumer(){
}

public void ConsumeService(){
_Service.DoSomething();
}
}
}

 

UNFINISHED: I’ll build more onto this post later.

 

Links:

powered by metaPost

I searched today for a good concise, precise, and clear definition of Separation of Concerns.

Surprisingly, for such an important software design concept, I ran into mostly gunk. Wishy washy, vague hand waving gestures at the pattern in almost religious hushed tones…with nobody able to get much closer than it is

  • a means of tackling a problem in parts (ie clarity of purpose)
  • coding it in parts so that changes to it cause the less change to over parts of the application (ie modular)

Beyond that, it quickly got unclear as to how to actually implement the concepts.

 

And then I came across this link. It certainly isn’t concise. Put it sure it precise.
So it’s a keeper for anyone trying to ensure they are very clear as to what the term Separation of Concern actually means.

powered by metaPost

Pretty much the foundation of the MVC pattern, The essence of the GoF Observer Pattern is as follows:

image

interface IPublisher {
void Attach(ISubscriber subscriber);
void Detach(ISubscriber subscriber);
void Notify();
}
interface ISubscriber {
void Notify(IPublisher sender);
}
public abstract class Stock : IPublisher{
public abstract string Name;
public abstract double Price{
get {return _Price;}
set {
if (Price == _Price){return;}
_Price = Price;
Notify();
}
}
private double _Price;

#region Implementation of IPublisher
List<ISubscriber> _Subscribers =
new List<ISubscriber>();
void Attach(ISubscriber subscriber){
_Subscriber.Add(subscriber);
}
void Detach(ISubscriber subscriber){
_Subscriber.Remove(subscriber);
}
void Notify(){
foreach(ISubscriber subscriber in _Subscribers){
subscriber.Notify(this);
}
}
#endregion
}
public class IBM : Stock {
IBM(double price){Name = "IBM";Price = 10.00;}
}

public class Investor : ISubscriber{
public void Notify(Stock stock ){
Console.WriteLine(stock.Price changed);
}
}
}

 

Terminology:

Observer: The ISubscriber interface

ConcreteObserver: The implementation of Observer interface (ie, Investor class).

Subject: The IPublisher interface

ConcreteSubject: Implementation of IPublisher interface (ie, Stock class).

 

How it relates to MVC, etc:

The pattern is used a lot in Silverlight and other places where the MVC (or spin offs) are used, in such that the Model (eg: a collection of Items) is expected to raise events (INotifyPropertyChanged/PropertyChangedEventArgs) and (INotifyCollectionChanged/CollectionChangedEventArgs), that the View subscribes to and updates the UI accordingly.

 

Links:

http://en.wikipedia.org/wiki/Observer_pattern

The observer pattern is a subset of the pub/sub pattern

powered by metaPost

Age old question when dealing with moving to LINQ to handle queries…and even before actually.

The answer is …although anonymous types are great…use with caution.

 

I clearly understand the motivation for the question,  btw, but there is a reason that the Framework doesn't allow vars to remain typed beyond the context in which they were instantiated...

First of all, anonymous types, are maybe anonymous, but they do take space. Each time you define a var, you are actually defining a class. Load your assembly up with tons of vars, each one slightly different than the last, or even exactly the same as each other, but just in different contexts, and you're increasing the size of your assembly...

Another aspect of the answer I found well documented in a code project article (see links on this page):

"If our intent for this data is to fill a simple list control, we do not need all the fields in the table. All we really care about for our list is the primary key and the textual representation of each record.
...
In beta versions of LINQ to SQL, we were able to force which fields were loaded into the entity object we were retrieving.
It turns out, this was a bug.
The thinking is, if one developer calls on data from a library, layer, or other code written by another developer, there would be mass confusion if that retrieved entity had missing data in the properties.
For example, if I call a method from a library that another developer wrote that retrieves our project list and only gets the ProjectId and Name, I could become very lost when I try to access the EstimatedDuration property.
Things would be bad enough if a field is not nullable and has uninitialized data, but imagine the EstimatedDuration property which is nullable. I may presume that there is no such value in the database, when in fact, there may be.

Therefore, when LINQ to SQL was released, this kind of thing is no longer allowed.
I still need the ability to retrieve just some fields from a table though, and I can.
I can use anonymous types locally, but if I want to pass the results around, I need to create a new class to hold just those values I desire and then use a new instance of the class when retrieving the data.
"

In other words, a) returning partial results is possible, b) use anonymous types maybe...c) but maybe have a preference for a Typed class that you create, not called Project, but maybe called ProjectSummary (you can have ProjectSummaryI, ProjectSummaryII, ProjectSummaryIII by the way…).

powered by metaPost

Did this about two years ago, but didn’t document it that time.

 

Create a local SqlServer Compact Database

Right – use Visual Studio to make a new local SqlServer Compact (*.SDF) Database:

image

After, that, you can create your tables using Visual Studio’s minimal Db exploration tools, or use the new and improved Microsoft Sql Server Management Studio 2008 to create a Sql Server Compact (a *.SDF) database:

 

image

 

 

 

Create the Tables within the database


Either way, you’ll be able to go and build some tables by right clicking the database/Tables and selecting New Table:

image

add defining the table name and columns to add to it:

 

image

In our simple case you get some barking mad tables (Pet, Feeding, Menu):

image

 

 

 

 

build a DBML File

[UPDATE: There’s actually an easier way than using the command prompt to generate *dbml files , which I’ll describe further down the post, but I think the following is still useful, to understand how it all fits together…]

Now…the problem is that Visual Studio 2005 and Visual Studio 2008 do not provide an inbuilt designer for Linq2SQL based on SqlServer Compact databases (say what?!?!)…you have to do it by hand. In fact, if you drag the tables from the Server Explorer onto a "Linq to Sql Classes (ie, a dbml) file, you’ll get the following error:

image

 

What is surprising by that is that that its pretty trivially easy to do it by hand.

 

Open the Visual Studio Command Prompt:

cd to the directory where the *.sdf lives, and enter

SQLMETAL “localdb.sdf” /dbml:”LocalDbContext.sdf”

This will spit out a file in current directory (which, since we’ve CD’d to it via the command prompt means it will dump it in the same directory as the *.sdf, which is our application’s base directory)….

 

Import the DBML into Visual Studio

So far, painless…now let’s return to Visual Studio, where we ensure we can see every file (using Project/Show All Files):

 

image

…and refresh the Solution Explorer:

image

In order to see the new *.dbml file you just generated:

image

Note that we’re looking at just one file, that once it’s added to the project, looks like this:

image

Note that :

  • Visual Studio automatically built the designer *.cs file that you are used to…
  • The namespace was not defined on the command line, but by Visual Studio as it was imported…(making it quite easy, really).
  • The IDE show’s the relationships in the designer:

image

It’s not an editable surface – but at least, one can get on with coding.

 

 

 


Add the Connection String to the database:

First things first – we need a connection string defined in the config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="localDbConnection"
connectionString="Data Source=localDb.sdf;Persist Security Info=False;"
providerName="Microsoft.SqlServerCe.Client.3.5" />
</connectionStrings>
</configuration>



 

 

Code up:

From there on in, we’re talking about mostly the same tools as for Sql2Link on Sql Express:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace XAct.Study._35.Linq2SQL
{
public class TestPage
{
public void InsertAPet()
{
ConnectionStringSettings connectionStringSettings =
ConfigurationManager.ConnectionStrings["localDbConnection"];

using (Localdb contextContext =
new Localdb(connectionStringSettings.ConnectionString))
{
Pet newPet = new Pet();
...
context.Pet.InsertOnSubmit(newPet);
...
contextContext.SubmitChanges();

}


}
}
}

 

TIP:

When coding you may run into one error that could baffle you a second…basically, that Count(), and a whole bunch of other LINQ 2 SQL methods are ‘missing’ from IntelliSense.

You may even get the following error:

Error    3    Could not find an implementation of the query pattern for source type 'System.Data.Linq.Table<XAct.Study._35.Linq2SQL.Pet>'.  'Where' not found.  Are you missing a reference to 'System.Core.dll' or a using directive for 'System.Linq'?    E:\XActStudy\Study\XAct.Study.35.Linq2SQL\XAct.Study.35.Linq2SQL\TestPage.cs    27    42    XAct.Study.35.Linq2SQL

Read it. Again. What’s it saying…? Yes…you have System.Core…but what about suggestion two..? Did you do it? Is there a “using System.Linq” at the top of the page…? Thought so…

Now Count() and everything else similar will come online via IntelliSense, as expected.

 

UPDATE:
There’s an even easier way to make the DBML file, actually…
Go to Tools/External Tools... and create a new entry with the following Values:

Title
Make &Linq classes for Database

Command
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SqlMetal.exe

Arguments
$(ItemPath) /dbml:$(ItemFileName).dbml

Initial Dir
$(ItemDir)

 

image

This menu button will then show up under the Tools menu, at which point you can select an *.sdf file in the Solutions Explorer, and then select Tools/Make Linq files for database…

That's pretty simple, right?

 

UPDATE:

Ha! Look at that…there’s a project to make it (arguably) even easier: http://www.codeplex.com/sqlmetalosui

 

UPDATE:

Posted by Daniel Moth on 11/13/2007
“It is probably worth pointing out that this only works for SQL CE on the desktop. I.e. LINQ to SQL is not supported by the Compact Framework and hence this would not work for SQL CE on Windows Mobile etc...”

powered by metaPost

             
    #G.A       Minimize  

             
Copyright 2007 by Sky Sigal