Factory Pattern in C#

M

Michaela Brauner

Hello together,

I'looking for a good instruction.
I found this one.
http://www.dofactory.com/Patterns/Patterns.aspx
Abstract Factory Creates an instance of several families of classes
Builder Separates object construction from its representation
Factory Method Creates an instance of several derived classes
Prototype A fully initialized instance to be copied or cloned
Singleton A class of which only a single instance can exist

My target, my goal is like this.
App.exe V1.0.0.1
IModul01 -- Module_Version01.dll
IModul02 -- Module_Version01.dll
IModul03 -- Module_Version01.dll
IModul04 -- Module_Version01.dll
IModul05 -- Module_Version01.dll

After n time some improvements in module3 was necessary.

App.exe V1.0.0.1
IModul01 -- Module_Version01.dll
IModul02 -- Module_Version01.dll
IModul03 -- Module_Version02.dll ####
IModul04 -- Module_Version01.dll
IModul05 -- Module_Version01.dll

### Without new compile, application, I would like to send the new dll
to the customer. No new exe, no changes in the interface, only the DLL!!

I now check on the right model.
Can somebody help me.
What is the right intonation. Which factory model?

Have somebody sample code in C#, VS2008 ?

The exe check the DLL and loads the right.

Many greetings Michaela
 
G

Gregory A. Beamer

Michaela Brauner said:
Hello together,

I'looking for a good instruction.
I found this one.
http://www.dofactory.com/Patterns/Patterns.aspx
Abstract Factory Creates an instance of several families of classes
Builder Separates object construction from its representation
Factory Method Creates an instance of several derived classes
Prototype A fully initialized instance to be copied or cloned
Singleton A class of which only a single instance can exist

My target, my goal is like this.
App.exe V1.0.0.1
IModul01 -- Module_Version01.dll
IModul02 -- Module_Version01.dll
IModul03 -- Module_Version01.dll
IModul04 -- Module_Version01.dll
IModul05 -- Module_Version01.dll

After n time some improvements in module3 was necessary.

App.exe V1.0.0.1
IModul01 -- Module_Version01.dll
IModul02 -- Module_Version01.dll
IModul03 -- Module_Version02.dll ####
IModul04 -- Module_Version01.dll
IModul05 -- Module_Version01.dll

Much of this depends on how the reference is bound and how the application
is configured. If the references bind to a particular version, you can trick
the app to accept the new version by keeping the same version number, but
that is very kludgy. You can also specify to accept newer versions
automatically. Or, if you have referenced in the config, you have the option
of not specifying a particular version. Just don't rename the actual DLL, or
you can get end with a mighty crash. ;-)

The factory pattern will not solve the "pop a new assembly in the bin"
problem. Now will prototypes or builders. Singleton is not applicable.

--
Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

************************************************
| Think outside the box! |
************************************************
 
P

Peter Duniho

Michaela said:
[...]
### Without new compile, application, I would like to send the new dll
to the customer. No new exe, no changes in the interface, only the DLL!!

I now check on the right model.
Can somebody help me.
What is the right intonation. Which factory model?

As Gregory suggests, the question of updating your implementation is
orthogonal to the question of the API design (i.e. whether you use a
factory pattern, singleton, whatever).

Assuming you don't rename the DLL itself, updating the DLL is simply a
matter of deploying a new version of the same DLL. If you want to
rename the DLL, then you should probably also rename the type(s)
implementing whatever you need from the DLL and then use some kind of
plug-in style architecture to retrieve from the DLL the implementation
you want.

I strongly suggest just using the "update the DLL, keep the same name
for DLL and types" approach. It will be much simpler.

Pete
 
M

Michaela Brauner

Hi,

Do you have a sample code?
C#, VS2008 ?


Thanks a lot.

Greeting Michaela
 
M

Michaela Brauner

Hello,
Do you mean example code for design patterns? If so, look at this site:
http://www.dofactory.com/Patterns/Patterns.aspx.
thanks.

Overview
http://www1.minpic.de/bild_anzeigen.php?id=110654&key=78643808&ende

Why do I can the not defined the delegate 'EventHandlerScannerVerify'in
my concrete scanner-class A?
What is the reason?
How looks the solution?


Thanks.
Greeting Michaela




Is state

Factory with n-Scanner for selection.
Idee:
Factory
ScannerProducts
Interface --- Event, Delegate
Basis class
Scannertype class fix

Interface:
public delegate void EventHandlerScannerVerify(Object sender,
NotifyEventArgsHardware e);
public interface IScannerVerify
{
event EventHandlerScannerVerify EvHaScannerVerify;
int ComPortOpen();
void ComPortClose();
string Read();
void TriggerStart(string sequence);
}
Base class:
public abstract class BaseScannerVerify : IScannerVerify
{
protected string ReadCode { get; set; }
public event EventHandlerScannerVerify EvHaScannerVerify;

public virtual int ComPortOpen()
{
return 0;
}

public virtual void ComPortClose()
{
}

public virtual string Read()
{
return ReadCode;
}

public virtual void TriggerStart(string sequence)
{
}

// public virtual void EvHaScannerVerifyFunctionAsynchron(string
data)
public void EvHaScannerVerifyFunctionAsynchron(string data)
{
if ( this.EvHaScannerVerify != null )
{
this.EvHaScannerVerify(this, new
NotifyEventArgsHardware(data));
}
}
}
Konkrete Scannerklasse
public class ScannerVerifyTypeA : BaseScannerVerify
{
//private string ReadCode { get; set; }
//public event EventHandlerScannerVerify EvHaScannerVerify;

public override int ComPortOpen()
{
return 0;
}

public override void ComPortClose()
{
}

public override string Read()
{
ReadCode = "2010-04-29-TestCode--A";
EvHaScannerVerifyFunctionAsynchron(ReadCode);
return ReadCode;
}

public override void TriggerStart(string sequence)
{
}

// // public override void
EvHaScannerVerifyFunctionAsynchron(string data)
// public void EvHaScannerVerifyFunctionAsynchron(string data)
// {
// if ( this.EvHaScannerVerify != null )
// {
// this.EvHaScannerVerify(this, new
NotifyEventArgsHardware(data));
// }
// }
}
 
P

Peter Duniho

Michaela said:
Hello,
thanks.

Overview
http://www1.minpic.de/bild_anzeigen.php?id=110654&key=78643808&ende

Why do I can the not defined the delegate 'EventHandlerScannerVerify'in
my concrete scanner-class A?

You can only access as a field the event you've declared from within the
class that declares it. Any other class, including sub-classes, see
only the event itself, which has only add and remove accessors, which
are used using "+=" or "-=" only.

If you want the sub-class to be able to raise the event, you need to
provide a method in the base class for that purpose. A common .NET
pattern is to have an "On…" method that does that. But you've already
got a method in your base class that should work for that purposes:
"EvHaScannerVerifyFunctionAsynchron". Just call that from the base class.

Pete
 
M

Michaela Brauner

Hello Peter,

I make now this way.
If you want, you can say good, bad or make improvements. Thanks.


http://www1.minpic.de/bild_anzeigen.php?id=110849&key=21919068&ende

Interface:

namespace Brauner.Hardware.Definitions.Core
{
public delegate void EventHandlerScannerVerify(Object sender,
NotifyEventArgsHardware e);

public enum ScannerState
{
NotDefine = -1,
Good = 0,
Bad = 1
}
public interface IScannerVerify
{
// Return always the last scanned code.
string LastCode { get; set; }
// Initialize (setup) scanner.
void Initialize();
// Start asynch operation.
void Scan();
// Return current state.
ScannerState State { get; set; }
// Stop asynch operation.
void Stop();


// Event raised when new barcode is scanned.
//event EventHandler Scanned; // standard
event EventHandlerScannerVerify Scanned; // overwrite with a
delegate
}
}

Base class
namespace Brauner.Hardware.Definitions.Core
{
public abstract class BaseScannerVerify : IScannerVerify
{
// public event EventHandler Scanned; standard
//public virtual event EventHandlerScannerVerify Scanned; //
overwrite with the own handler, delegate
public virtual event EventHandlerScannerVerify Scanned; //
overwrite with the own handler, delegate

public virtual void Scan()
{
}

//public virtual void OnScanned(string data)
public virtual void OnScanned(string data)
{
if (this.Scanned != null)
{
this.Scanned(this, new NotifyEventArgsHardware(data));
}
}

// Return always the last scanned code.
public string LastCode { get; set; }

// Initialize (setup) scanner.
public virtual void Initialize()
{
}

// Return current state.
public virtual ScannerState State { get; set; }

// Stop asynch operation.
public virtual void Stop()
{
}
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Brauner.Hardware.Definitions.Core;
using System.ComponentModel;



namespace Brauner.Hardware.Implementations.ScannerVerify.ScannerA.Core
{
public class ScannerVerifyTypeA : BaseScannerVerify
{
public override event EventHandlerScannerVerify Scanned; //
overwrite with the own handler,

delegate

public override void Scan()
{
BackgroundWorkerScannerTypeA bw = new
BackgroundWorkerScannerTypeA();
bw.RunAsync(new

RunWorkerCompletedEventHandler(RunAsyncBackgroundWorkerCompleted_Scan));
}

private void RunAsyncBackgroundWorkerCompleted_Scan(object sender,

RunWorkerCompletedEventArgs e)
{
BackgroundWorkerScannerTypeA bwSender =
(BackgroundWorkerScannerTypeA)sender;

OnScanned(bwSender.Result);
}


public override void OnScanned(string data)
{
if (this.Scanned != null)
{
data += " noch Zusatz, deshalb override speziell für A";

this.Scanned(this, new NotifyEventArgsHardware(data));
}
}

// Initialize (setup) scanner.
public override void Initialize()
{
}

// Return current state.
public override ScannerState State { get; set; }

// Stop asynch operation.
public override void Stop()
{
}
}

class BackgroundWorkerScannerTypeA :
System.ComponentModel.BackgroundWorker
{
// object

// in parameters

// out parameters
public string Result { set; get; }

// start function
public void RunAsync(RunWorkerCompletedEventHandler completed)
{
this.DoWork += new DoWorkEventHandler(ThreadProc);
this.RunWorkerCompleted += completed;
this.RunWorkerAsync();
}

// thread proc
private void ThreadProc(object sender, DoWorkEventArgs e)
{
BackgroundWorkerScannerTypeA bw =
(BackgroundWorkerScannerTypeA)sender;
System.Diagnostics.Debug.Assert(this == bw);

System.DateTime dtStart = System.DateTime.Now;

// ** ToDo implement - Serial Port, Scanner DataReceived
System.Threading.Thread.Sleep(8000);

bw.Result = "Hallo über BackgroundThread";

System.DateTime dtEnd = System.DateTime.Now;
System.TimeSpan tsDuration = dtEnd.Subtract(dtStart);
double dDuration = tsDuration.TotalMilliseconds;
System.Diagnostics.Trace.TraceInformation("GetScanCode
duration={0} ms", dDuration);
e.Cancel = this.CancellationPending;
}
}
}
 
P

Peter Duniho

Michaela said:
Hello Peter,

I make now this way.
If you want, you can say good, bad or make improvements. Thanks.

Some broad observations:

• ScannerState: unless your enum is required to have specific values
for the purpose of interoperation with some other component (managed or
unmanaged) that you don't control, there really is not any point in
providing explicit values for each enumeration value.

• BaseScannerVerify: there are no abstract members of this abstract
class. Thus, there is not any point in making the class abstract. If
there are members of the class that you want to require sub-classes to
override, then those members should not be implemented in the base
class. Make them abstract instead.

• ScannerVerifyTypeA: currently, the base class provides default
implementations for every member. There is no point in the sub-class
overriding the base class implementations for members for which it does
not change the implementation. This includes the "Initialize()" and
"Stop()" methods, and the "State" property.

• BackgroundWorkerScannerTypeA: there is almost never any point in
overriding BackgroundWorker, and definitely in your example there's
really no obvious benefit to doing so. Even if you wanted a convenience
method such as the "RunAsync()" method, there's nothing about that
method that suggests it should actually be _in_ an instance of
BackgroundWorker.

• BackgroundWorkerScannerTypeA: your DoWork event handler sets the
Cancel property at the end based on the CancellationPending. But, the
worker object hasn't had its WorkerSupportsCancellation property set to
true. Even if it had, the Cancel property should be set _only_ if the
DoWork event handler was in fact actually cancelled. If it runs to
completion, then in spite of some client code trying to cancel the
worker (resulting in the CancellationPending property getting set), by
definition the worker was not in fact cancelled, and should not report
that it was.

Pete
 
M

Michaela Brauner

Hello Peter,
Some broad observations:
thanks a lot for the obervations.
Can you show me concretely at the code.
• ScannerState: unless your enum is required to have specific values
for the purpose of interoperation with some other component (managed or
unmanaged) that you don't control, there really is not any point in
providing explicit values for each enumeration value.

• BaseScannerVerify: there are no abstract members of this abstract
class. Thus, there is not any point in making the class abstract. If
there are members of the class that you want to require sub-classes to
override, then those members should not be implemented in the base
class. Make them abstract instead.

• ScannerVerifyTypeA: currently, the base class provides default
implementations for every member. There is no point in the sub-class
overriding the base class implementations for members for which it does
not change the implementation. This includes the "Initialize()" and
"Stop()" methods, and the "State" property.

• BackgroundWorkerScannerTypeA: there is almost never any point in
overriding BackgroundWorker, and definitely in your example there's
really no obvious benefit to doing so. Even if you wanted a convenience
method such as the "RunAsync()" method, there's nothing about that
method that suggests it should actually be _in_ an instance of
BackgroundWorker.

• BackgroundWorkerScannerTypeA: your DoWork event handler sets the
Cancel property at the end based on the CancellationPending. But, the
worker object hasn't had its WorkerSupportsCancellation property set to
true. Even if it had, the Cancel property should be set _only_ if the
DoWork event handler was in fact actually cancelled. If it runs to
completion, then in spite of some client code trying to cancel the
worker (resulting in the CancellationPending property getting set), by
definition the worker was not in fact cancelled, and should not report
that it was.
Then it becomes clearer for me. Have a nice Sunday.
Greeting Michaela
 
M

Michaela Brauner

Hello Peter,

the reason for 'abstract' class was.
I don't know what is in the future?
Maybe some Scanners have same features.
What do you think about that?

Michaela
 
P

Peter Duniho

Michaela said:
Hello Peter,

the reason for 'abstract' class was.
I don't know what is in the future?
Maybe some Scanners have same features.
What do you think about that?

I think it doesn't make sense.

If in the future the base class changes in a way that actually requires
the "abstract", that would mean you'd either add abstract members or
change existing members to abstract. In which case, existing code would
have to be recompiled to use the same the DLL anyway. It would be
simple enough to change the class to "abstract" at that point as well.

There is no reason I can see to have a class be "abstract" now when
there's nothing abstract about it.

Pete
 
M

Michaela Brauner

Peter said:
I think it doesn't make sense.

If in the future the base class changes in a way that actually requires
the "abstract", that would mean you'd either add abstract members or
change existing members to abstract. In which case, existing code would
have to be recompiled to use the same the DLL anyway. It would be
simple enough to change the class to "abstract" at that point as well.

There is no reason I can see to have a class be "abstract" now when
there's nothing abstract about it.
ok thanks.

Do you have, do you know a good sample, link for my task?
So I can see, maybe the better way.

But not with the new framework. I haven't VS2010, only VS2008
http://mef.codeplex.com/
http://msdn.microsoft.com/de-de/library/dd460648.aspx#the_problem_of_extensibility
I need, to understand first the basics pattern.

Thanks a lot.

Greeting Michaela
 
P

Peter Duniho

Michaela said:
[...]
There is no reason I can see to have a class be "abstract" now when
there's nothing abstract about it.

ok thanks.

Do you have, do you know a good sample, link for my task?
So I can see, maybe the better way.

But not with the new framework. I haven't VS2010, only VS2008
http://mef.codeplex.com/
http://msdn.microsoft.com/de-de/library/dd460648.aspx#the_problem_of_extensibility

I need, to understand first the basics pattern.

Which pattern are you referring to? The factory pattern (which you
originally seem to have asked about)? Or the abstract class design
(which you seem to be trying to implement)?

Not that I have any good links that I personally can vouch for, to refer
you to off-hand. But you should at least be specific about what you're
looking for.

I will point out that Wikipedia has articles on both the factory pattern
and abstract class design:
http://en.wikipedia.org/wiki/Factory_pattern
http://en.wikipedia.org/wiki/Abstract_class

Though, on the latter point, to the extent that an abstract class is
basically the same as an interface, except that it can have some default
implementation for members, it doesn't seem to me as though that's
really all that complicated a subject. My previous comments regarding
your code should give you some insight as to important differences
between an abstract class as you've implemented it, and the more typical
ways to implement one (*).

(*)(in particular, if you have implemented all of the virtual members
already, there's no point in the class being abstract; only if some
members are themselves abstract, and thus much like an interface that
some type might need to implement, would the whole class need to be
abstract).

Note that neither of these issues are in any way specific to a given
version of Visual Studio.

I also don't understand the intent behind the links you posted. The
first doesn't seem specifically applicable to the question at hand, and
the second I can't even understand (I appreciate that your English is
better than my German and certainly don't fault you for referring to
German sources, but unfortunately there is little hope of me figuring
them out).

Pete
 
M

Michaela Brauner

Hello Peter,
Which pattern are you referring to? The factory pattern (which you
originally seem to have asked about)? Or the abstract class design
(which you seem to be trying to implement)?
My task is.
MyApplication.exe
Machine - Factory
Scanner - Products
The machine needs one scanner from n scanner.

I prefer the correct pattern. I'm looking for that.
MyApplication.exe shoould be run without new compile withe different dll's.
Not more.
....

I also don't understand the intent behind the links you posted. The
first doesn't seem specifically applicable to the question at hand, and
the second I can't even understand (I appreciate that your English is
better than my German and certainly don't fault you for referring to
German sources, but unfortunately there is little hope of me figuring
them out).
Of course, I think so. Sorry.

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

Managed Extensibility Framework (MEF) that offers more extensibility
points than previous versions of the..

Micosoft know that problem and make improvements, but I haven't VS2010,
only VS2008.

And I want to learn, make first on the 'normal' way.

Maybe you have a short good example.

Have a nice day
Michaela
 
P

Peter Duniho

Michaela said:
Hello Peter,
My task is.
MyApplication.exe
Machine - Factory
Scanner - Products
The machine needs one scanner from n scanner.

I prefer the correct pattern. I'm looking for that.

The factory pattern may or may not be the best approach. It probably
is, but it will depend on the exact architecture. Specifically, how an
individual scanner is represented in your design.
MyApplication.exe shoould be run without new compile withe different dll's.
Not more.

This has nothing at all to do with the question of whether to use the
factory pattern or not.
http://en.wikipedia.org/wiki/Microsoft_Visual_Studio

Managed Extensibility Framework (MEF) that offers more extensibility
points than previous versions of the..

Micosoft know that problem and make improvements, but I haven't VS2010,
only VS2008.

I'm surprised there's not a .NET 4 SDK that can be used with VS2008.
But it appears that's the case.

However, you can always upgrade to VS2010. The Express versions are
free, if you can't justify paying for the retail versions.

That said, while MEF can be an effectively way to populate the types
supported by a factory class, it also is not related specifically to the
factory pattern.

And again, with or without the factory pattern, you may or may not find
it useful to declare an abstract base class for your factory objects (or
even a non-abstract base class).

These three things are all independent choices with respect to the
design and implementation of your program. You can use any one of them
independently of whether you use any of the others.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top