Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How can I prevent the host application from crashing, due to any uncaught exceptions in the instances of a dynamically loaded external DLL?
Right now I have something like the following setup, please note that this is not the exact implementation:
internal class ExtensionManager
{
private static Type mExtension;
public static GetExtension() { return mExtension; }
ExtensionManager()
{
FileInfo[] fis = null;
fis = directory.GetFiles("*.dll");
foreach (FileInfo file in fis)
{
Assembly assembly = Assembly.LoadFrom(file.FullName);
if(some condition)
{
mExtension = Assembly.GetTypes().FirstOrDefault(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(BaseExtension)));
break;
}
}
}
}
internal class Room
{
public Room()
{
StartExtensions();
}
private BaseExtension CreateInstance(Type classType)
{
BaseExtension instance = null;
try
{
instance = (BaseExtension)Activator.CreateInstance(classType, new object[] { this });
}
catch (Exception error)
{
LogException("[Room][CreateInstance()]", error);
}
return instance;
}
private void StartExtensions()
{
if (!mExtensionInitialised)
{
Type classType = ExtensionManager.GetExtension();
if (classType == null) return;
if (classType.BaseType != typeof(BaseExtension)) return;
Task<BaseExtension> task = Task<BaseExtension>.Factory.StartNew(() => CreateInstance(classType), TaskCreationOptions.LongRunning);
try
{
task.Wait();
}
catch (Exception error)
{
//
}
}
}
}
class Program
{
static List<Room> mRooms = new List<Room>();
static void Main(string[] args)
{
for(int i = 0; i < 100; i++)
{
Room room = new Room();
mRooms.Add(room);
}
}
}
So I need to figure out if there is a uncaught exception, at run-time in the instance created by BaseExtension CreateInstance(Type classType).
P.S .NET Plugin framework is not an option, at the moment for me.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Having the following problem. Article goes through several stages before being published by several different Roles.
Writer -> writes
Approver -> approves
Admin -> Publishes
Design a program that allow for maximum extensibility:
This is what I have. Can someone please let me know if this is the right approach? is there a better one?
public interface IRole
{
IRole Write();
IRole Approve();
IRole Publish();
}
internal class Writer : IRole
{
public IRole Write()
{
return new Approver(); // next needs approval
}
public IRole Approve()
{
return this;
}
public IRole Publish()
{
return this;
}
}
internal class Approver : IRole
{
public IRole Write()
{
return new Writer();
}
public IRole Approve()
{
// publish
return new Admin();
}
public IRole Publish()
{
return this;
}
}
internal class Admin : IRole
{
public IRole Write()
{
return new Writer();
}
public IRole Approve()
{
return new Approver();
}
public IRole Publish()
{
return this;
}
}
internal class Article
{
public Article()
{
role = new Writer();
}
private IRole role { get; set; }
public void Write()
{
role = role.Write();
}
public void Approve()
{
role = role.Approve();
}
public void Publish()
{
role = role.Publish();
}
}
private static void Main(string[] args)
{
var article = new Article();
article.Approve(); // can't do - write first
article.Write();
article.Publish(); // can't do
article.Approve(); // can
article.Write(); // can go back
article.Approve(); // can
article.Publish();
}
What you are looking for is called "Chain of Responsibility". It is a design pattern that allows operations to be chained one after the other. Your use case will perfectly fit with this pattern. https://www.codeproject.com/Articles/594974/Chain-of-Responsibility-Pattern
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
What I'm wondering is what would be the best performance for determining what child class was actually passed into the function.
Here are the 3 different ways I am going between for what would be the best performance:
(ACHData, CCData, and DC Data all Inherit from BaseData)
public BaseProcessor GetProcessor(BaseData paymentInfo)
{
if (paymentInfo.GetType() == typeof(ACHData))
{
return GetACHProcessor((ACHData)paymentInfo);
}
else if (paymentInfo.GetType() == typeof(CCData))
{
return GetCCProcessor((CCData)paymentInfo);
}
else if (paymentInfo.GetType() == typeof(DCData))
{
return GetDCProcessor((DCData)paymentInfo);
}
else
{
throw new Exception(ExceptionMessage);
}
}
public BaseProcessor GetProcessor(BaseData paymentInfo)
{
if (paymentInfo is ACHData)
{
return GetACHProcessor((ACHData)paymentInfo);
}
else if (paymentInfo is CCData)
{
return GetCCProcessor((CCData)paymentInfo);
}
else if (paymentInfo is DCData)
{
return GetDCProcessor((DCData)paymentInfo);
}
else
{
throw new Exception(ExceptionMessage);
}
}
public BaseProcessor GetProcessor(BaseData paymentInfo)
{
var achInfo = paymentInfo as ACHData;
if (achInfo != null)
{
return GetACHProcessor(achInfo);
}
var ccInfo = paymentInfo as CCData;
if (ccInfo != null)
{
return GetCCProcessor(ccInfo);
}
var dcInfo = paymentInfo as DCData;
if (dcInfo != null)
{
return GetDCProcessor(dcInfo);
}
throw new Exception(ExceptionMessage);
}
I would re-think your entire design. Have your classes implement an interface that forces them to choose what to provide as a processor:
public interface IKnowWhatProcessorIWant {
IProcessor CreateProcessor();
}
public class ACHData : BaseData, IKnowWhatProcessorIWant {
public IProcessor CreateProcessor() {
return new GetACHProcessor(this);
}
}
Then your GetProcessor code becomes:
public BaseProcessor GetProcessor(IKnowWhatProcessorIWant obj) {
return obj.CreateProcessor();
}
...or, you could omit that method entirely then.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Code below is for factory method pattern I would like it to be verified. if not valid then what are the changes that need to be made.
here i have added both client code from where the pattern is made use and the code for implementation of pattern.
the example i have used here is of TV remote which acts as factory and returns me TV channel object based on the channel number.
client code
private void button3_Click(object sender, EventArgs e)
{
ITVChannelNew channelNew;
channelNew = RemoteNew.getChannel(1);
currentProgram = channelNew.getCurrentShow();
channelNew = RemoteNew.getChannel(2);
currentProgram = channelNew.getCurrentShow();
}
Factory method code
namespace WindowsFormsApplication1
{
public interface ITVChannelNew
{
string getCurrentShow();
string getNextShow();
string getPreviousShow();
}
public class TVChannelNew : ITVChannelNew
{
private readonly string previous;
private readonly string current;
private readonly string next;
public TVChannelNew(string previous, string current, string next)
{
this.previous = previous;
this.current = current;
this.next = next;
}
public string getCurrentShow()
{
return current;
}
public string getNextShow()
{
return next;
}
public string getPreviousShow()
{
return previous;
}
}
public class BBCNew : TVChannelNew
{
public BBCNew():base("BBC previous","BBC current","BB next")
{
}
}
public class TimesNowNew : TVChannelNew
{
public TimesNowNew()
: base("TimesNow previous", "TimesNow current", "TimesNow next")
{
}
}
public static class RemoteNew
{
public static ITVChannelNew getChannel(int ChannelNumber)
{
switch (ChannelNumber)
{
case 1:
return new BBCNew();
case 2:
return new TimesNowNew();
default:
return new TimesNowNew();
}
}
}
}
Yes that looks good to me.
But for me I would want to have a clearer indication of what type I would expect on the client level. To do this I would define a enum somewhere such as:
public enum TVChannels
{
BBCNew,
TimesNowNew
}
And define the Factory like:
public static class RemoteNew
{
public static ITVChannelNew getChannel(TVChannels channel)
{
switch (channel)
{
case TVChannels.BBCNew:
break;
case TVChannels.TimesNowNew:
break;
default:
break;
}
}
}
This way you have clearer indication what type you want to return and also still leaves the client without knowing any of the concrete types, such as:
private void button3_Click(object sender, EventArgs e)
{
ITVChannelNew channelNew;
channelNew = RemoteNew.getChannel(TVChannels.BBCNew);
currentProgram = channelNew.getCurrentShow();
channelNew = RemoteNew.getChannel(TVChannels.TimesNowNew);
currentProgram = channelNew.getCurrentShow();
}
Also, if someone changed the numbers around in your factory (in the switch statement), it is not immediately clear that it is wrong. If he did spot something wrong he/she will have to ask 'what is channel 45 again?' or 'what is channel 3 meant to return?' and probably have to check some other source to check the correct values.
If you use the enumerations and someone swapped it around accidentally, the next person will stand a better chance in spotting a mistake due to the obvious wording.
Yes the factory looks fine too me, I would perhaps call the factory TVChannelNewFactory but otherwise it seems fine.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
static Eleve[] eleves = new Eleve[6];
static void Main(string[] args)
{
int[] notes;
eleves[0] = new Faineant("Schtroumpf", "Faineant");
eleves[1] = new Fourbe("Schtroumpf", "Fourbe");
eleves[2] = new Bon("Schtroumpf", "Bon");
eleves[3] = new Fayot("Schtroumpf", "Fayot");
eleves[4] = new PasTresBon("Schtroumpf", "PasTrèsBon");
eleves[5] = new PasTresBon("Schtroumpf", "PasTrèsBon 2");
eleves[1].triche(); //Here is the problem ! not swag.
}
*
class Personne
{ public virtual void triche() {}
public virtual void prepareLeCafe() { }
}
*
abstract class Eleve : Personne ;
*
class Tricheur : Eleve, ITricheur
{ void ITricheur.triche()
{
min = 15;
max = 15;
}
}
*
public interface ITricheur
{
void triche();
}
The method called when running "eleves[1].triche() ;" is the one in class Personne and not the one in class Tricheur : Eleve, ITricheur. Can someone explain us our error ? Thanks a lot !
In your case objects in Eleve[] must be of type Tricheur than it will take the implementation you want or all of your other classes (Faineant, Fourbe, ...) have also to implement the same implementation like Tricheur (but last is bad idea).
If Fourbe is a direct child of Eleve
The array you created is of type Eleve.
tatic Eleve[] eleves = new Eleve[6];
Eleve extends Personne and Personne contains a method triche. That is why the Personne.triche is getting called.
The class class Tricheur : Eleve, ITricheur is not actually comes after Eleve. So, there is no point for its triche to get called.
If Fourbe is a direct child of Tricheur
You need to override triche this way,
class Tricheur : Eleve, ITricheur
{
public void override ITricheur.triche()
{
min = 15;
max = 15;
}
}
Seems that you missed out something in your code example. I just added the missing parts from compiler and it works.
The question would now be: Do you like to get into Personne.triche() or into Tricheur.triche()?
internal class Program
{
private static Eleve[] eleves = new Eleve[6];
private static void Main(string[] args)
{
eleves[0] = new Tricheur("Schtroumpf", "Faineant");
eleves[1] = new Tricheur("Schtroumpf", "Fourbe");
eleves[2] = new Tricheur("Schtroumpf", "Bon");
eleves[3] = new Tricheur("Schtroumpf", "Fayot");
eleves[4] = new Tricheur("Schtroumpf", "PasTrèsBon");
eleves[5] = new Tricheur("Schtroumpf", "PasTrèsBon 2");
var eleve = eleves[1];
var tricheur = eleve as ITricheur;
if (tricheur != null)
tricheur.triche();
eleve.triche();
}
}
public interface ITricheur
{
void triche();
}
internal abstract class Eleve : Personne
{ }
internal class Personne
{
public virtual void prepareLeCafe()
{ }
public virtual void triche()
{ }
}
internal class Tricheur : Eleve, ITricheur
{
private int max;
private int min;
public Tricheur(string a, string b)
{
}
void ITricheur.triche()
{
min = 15;
max = 15;
}
}
Update
So to get into Tricheur.triche() you should change your implementation that way:
internal class Tricheur : Eleve, ITricheur
{
public Tricheur(string a, string b)
{
}
void ITricheur.triche()
{
// If you remove this method, you'll get
// always into the overriden method below.
}
public override void triche()
{
}
}
The two methods:
public virtual void triche() {}
and
void ITricheur.triche()
are two different methods. The letter one being an explicit implementation of ITricheur.triche.
In case you really want to create a virtual triche method in the ultimate ancestor, you have to override it in the descendant (regardless it's declared in the interface as well — the two will actually match), like this:
public override void triche() { … }
You have methods with same name at class and interface, by default you call method from Personne(parent) class. If you need call method from ITrecheur you must call
(eleves[1] as ITricheur).triche();
you issue is the following Tricheur inherits from Eleve so your debugger see the triche() as correct but at runtime will not do anything as virtual has no implentation and nothing will be executed
so you should do something like this
public class Personne {
public virtual void triche() { }
public virtual void prepareLeCafe() { }
}
public abstract class Eleve : Personne
{
public override void triche()
{
// here your code
}
}