I have two classes that are instantiaded and loaded at runtime. I would like to check the resources of one without having to refer the instances as it can get messy if there are a lot of checks and classes.
For example, if I have the two following classes and I want to call one from another.
Class Item
{
private int id;
private int loc;
void Item()
{
// the Class actually has some properties with get set, but thats not the point here.
id = 1;
loc = 2;
}
public bool check()
{
// Check if the several fields are ok for DB submission
// how Can I refer to the other class from here? Do I have to pass the instance as a parameter?
return Locals.Exists(loc); // does not work because its not static!
}
}
Class Locals
{
Hashtable l = new Hastable();
void Locals()
{
// This will actually be loaded from a DB at runtime.
l.add(1, "Local 1");
l.add(2, "Local 2");
}
public bool Exists(int i)
{
return l.ContainsKey(i);
}
}
//Form Code:
main()
{
Item newItem = new Item();
Locals allLocals = new Locals();
newItem.check();
}
Is there a way to do this without having to call
newItem.check(allLocals);
From what I saw, even with delegates, the caller classe need the instance of the other class.
In short, Is there another way to promote cross Instances communication?
Was I confusing enough?
not sure i understand what you mean, but i usually add for similiar cases a static list with all of the objects
Class Locals
{
public static List<Locals> MyLocals = new List<Locals>(); // first thing i add
Hashtable l = new Hastable();
void Locals()
{
// This will actually be loaded from a DB at runtime.
l.add(1, "Local 1");
l.add(2, "Local 2");
MyLocals.Add(this); // second thing i add
}
and then you can get the objects from a static context.
be sure to edit the dispose function as well, otherwise the GC will not work.
It's not entirely clear what you're trying to accomplish here, but one option to fix the problem of passing lots of instances around is to use an IoC framework (Ninject is one example, but there are several available to choose from.) Because instances are injected dynamically as your objects are constructed, this can help to reduce inconvenient glue code. There are other patterns available to allow the classes to find eachother (a Singleton instance or some form of Repository that allows lookup of an instance using some identifying data.) It's also possible to use a Message passing design, which strongly decouples the classes, at the cost of some additional overhead.
It really depends on what you're trying to do. Every design will have its pros and cons.
How can I refer to the other class
from here? Do I have to pass the
instance as a parameter?
Yes, the only way to communicate with an instance is to get a reference to it (or an intermediary). Since Locals isn't a static class, pass an instance to an Item constructor or method parameter.
Related
In the below adapter design pattern sample code, why a new class is introduced instead of using multiple interface in the client?
interface ITarget
{
List<string> GetProducts();
}
public class VendorAdaptee
{
public List<string> GetListOfProducts()
{
List<string> products = new List<string>();
products.Add("Gaming Consoles");
products.Add("Television");
products.Add("Books");
products.Add("Musical Instruments");
return products;
}
}
class VendorAdapter:ITarget
{
public List<string> GetProducts()
{
VendorAdaptee adaptee = new VendorAdaptee();
return adaptee.GetListOfProducts();
}
}
class ShoppingPortalClient
{
static void Main(string[] args)
{
ITarget adapter = new VendorAdapter();
foreach (string product in adapter.GetProducts())
{
Console.WriteLine(product);
}
Console.ReadLine();
}
}
I have the below queries related to the above code.
What, if ShoppingPortalClient directly inherits VendorAdaptee?
In which scenario we need adapter class?
why instead of simple inheritance a needed class, creating this pattern to access another class method?
Sometimes you have a given API that you can't change (legacy/external-library/etc...) and you want to make your classes be able to work with that API without changing their code.
Lets say you use an API which has an ISomethingToSerialize
public interface ISomethingToSerialize
{
object[] GetItemsToSerialize();
}
That API also has a Serialize function:
public class SerializationServices
{
byte[] Serialize(ISomethingToSerialize objectToSerialize);
}
Now you have a class in your code, and you don't want or not able to change it, let's call it MyUnchangeableClass.
This class doesn't implement ISomethingToSerialize but you want to serialize it using the API so you create AdapterClass which implement ISomethingToSerialize to allow MyUnchangeableClass to use it without implementing it by itself:
public class AdapterClass : ISomethingToSerialize
{
public AdapterClass(MyUnchangeableClass instance)
{
mInstance = instance;
}
MyUnchangeableClass mInstance;
public object[] GetItemsToSerialize()
{
return mInstance.SomeSpecificGetter();
}
}
Now you can use
MyUnchangeableClass instance = ... //Constructor or factory or something...
AdapterClass adapter = new AdapterClass(instance)
SerializationServices.Serialize(adapter);
to serialize an instance of MyUnchangeableClass even though it doesn't meet the requirements of the API by itself.
You've got the idea totally wrong. The VendorAdaptee is the instance of code that produce data, where the ShoppingPortalClient is the one who wants to consume it.
Let me explain what would be the real world situation. You are implementing the shop, and someone else has been implemented a service to give you data about their products(VendorAdaptee). The simple way of doing it is to simply call their methods and use the data, right? But it is their service and they might want to change it later while you don't want to upload your whole solution and release a new version. Therefore, you need an adapter in between to make sure that the data will be send to your real code with the format that you need, and you simply don't care about the address, method name or data format that has been supported by your vendor.
about your questions:
Inheritance is not in any way the case. Conceptually speaking, a shop is not a vendor in any way. considering the code, you have nothing similar in any of those 2, and the behavior is totally different. one is providing data while the other use it.
The main reason you would use an adapter is for legacy code that you don't want to mess with - or a third party that you won't to fit into a certain interface.
There are other reasons, usually depending on how you find easier to develop and if using the adapter design pattern makes sense to you. I don't see it as very useful in other cases though.
First of all I also don't think this is a good example for Adapter pattern. Adapter pattern is much meaningful when you can't directly use one particular kind of class(say A) in your class(say B), instead you implement another class(say C) which can be directly used inside your class (B) and it(C) can directly use the first one(A).
You might ask what will be the examples where B cannot directly use A. There's few.
A's methods don't return the type which is ideally needed by B.
So we don't to mess up with adding the conversion need by B inside B. Instead we give responsibility to C to do it for B.
It might not look natural for B to contain A. etc.
Back to your questions
(1) It is meaningful if you ask,
What, if ShoppingPortalClient directly 'uses' VendorAdaptee?
Just because it is the main class, it has been used as a demo, not to show the structure. And one thing to add, just because you want to call another class's method, don't inherit it unless it is meaningful. In this scenario composition is preferred. For the question why not 'using', just assume it cannot. But you rather ask why cannot. The answer I can give in this example is just assume it is not natural to call Adaptee. That's why I said it is not a good example. :)
(2), (3) I think you can get the answer from the description I have provided so far.
public class ScheduleRatesController
{
protected CoreDataManager dataManager;
public ScheduleRatesController()
{
dataManager = new CoreDataManager();
}
// testing
public ScheduleRatesController(CoreDataManager manager)
{
dataManager = manager;
}
public virtual void GetTranQuotesToFillRatesAndPayments(ref List<int> ids)
{
ids.AddRange(new List<int>());
}
}
So to give you guys some background, we're splitting one DB query into a bunch of different ones, and we want subclasses to basically each take on a DB call for their GetTranQuotesToFillRatesAndPayments() method that represents it's specific query.
What you see above is the base class I have. I made those two methods virtual as I plan on having subclasses override them to perform their own stuff. So one could be like:
public override void GetTranQuotesToFillRatesAndPayments(ref List<int> ids)
{
ids.AddRange(dataManager.GetLoanTranQuotes());
}
and etc. My question is, is this the best/cleanest way to perform a pattern like this?
The code that calls this is going to contain a huge list of filtered id's, that it's going to need to fill by calling each classes call to GetTranQuotesToFillRatesAndPayments(). Let me know if this doesn't make sense. I'm kind of getting turned off by the fact that I'm going to need to call the same method like 6 times, each on a different class. I think that might be messy in itself even though the goal of it was to make it clean. I don't want to have something like this on the calling side:
List<int> ids = new List<int>();
ScheduleRatesController controller = new LoanController();
controller.GetTranQuotesToFillRatesAndPayments(ref ids);
controller = new TradeController();
controller.GetTranQuotesToFillRatesAndPayments(ref ids);
etc.
Let me know if you need any more background or info.
Thanks.
Several design remarks:
Using the ref keyword usually indicates design problems and should be avoided. There is no need to pass a reference value using the ref keyword (any List<T> is always passed by reference). Your program would work equally without it.
A better idea than passing your list to the method would be to return your data from the method, and allow callers to decide what to do with it. Maybe you will only want to find a single value at some other place in your program, and creating a new list is an overkill. Also, you should try to add as little functionality as possible to each class (Single Responsibility Principle), and your class is right now responsible for fetching the data and deciding how it should be stored.
Naming: your method name is really complex. Also, the name "controller" doesn't usually represent an object responsible for fetching data.
On the other hand, you have a CoreDataManager class (btw, Manager is a bad suffix for any class), which appears to contain a bunch of methods which return various data. What is the need for ScheduleRatesController then? Does it only copy this to a list?
Business logic should be separated from your Data access layer. You should consider using Repository pattern, or similar (check this answer, for example), to ensure that your data class only fetches the data from the DB.
If you have several classes which need to fulfill a certain contract, start by creating the interface which they need to implement. Don't think about reusing code at this time. Your code, for example, forces all subclasses to use the CoreDataManager, while one day it may turn out that a certain "controller" might need to be composed of different objects.
Use a List<Func<List<int>,List<int>>>. Which is basically a list of functions with the following type signature:
List<int> MyFunc(List<int> foo);
You can then pass the list of functions to a method that works like the following:
public List<int> GetAllIds(List<Func<List<int>,List<int>>> functionList) {
var listOfIds = new List<int>();
foreach(var f in functionList) {
listOfIds = f(listOfIds);
}
return listOfIds;
}
You can use lambdas to compose functionList like so:
functionList.Add(list => {
list.AddRange(dataManager.GetLoanTranQuotes());
return list;
});
Now you do not have to depend on any specific inheritance hierarchy. You can use function composition to produce the whole list.
I am creating a class library for AutoCAD with .NET.
The problem is that the methods are called one after another from AutoCAD and first one reads input file and creates List of data in memory. However when the new one is called the list is empty.
I need to find a solution how to keep that data.
The List contains data in my created structure. Methods are called independently, but in order.
Short code example:
namespace GeoPjuvis
{
...
public class Program
{
...
//program variables
private List<GeoData> dataList;
private List<DataPoint> points;
private int mapScale;
public Program()
{
dataList = new List<GeoData>();
points = new List<DataPoint>();
}
//Initialization method of the program. Makes praperations. Reads files. Add points to map.
[CommandMethod("geoinit", CommandFlags.Session)]
public void Init()
{
...
}
//method uses data gathered before and selects points
[CommandMethod("selectPoints", CommandFlags.Session)]
public void SelectPoints()
{
...
}...
So why these dataList and points lists are empty when I call SelectPoints() method. And how to avoid that?
I don't know about programming for AutoCAD, but I'd suspect that it's creating a new instance each time. You could try making the variables static (e.g. class-level):
private static List<GeoData> dataList = new List<GeoData>();
Is it instantiating a new class each time it calls a method? (Forgive me, I'm not familiar with coding for AutoCAD.) Try making the class static. If that doesn't work, can you return the value(s) from the first method to AutoCAD and have it send those as arguments to the next method? That wouldn't be the best solution for performance, keep in mind.
Also, for reference, take a look at the a Singleton implementation in C#:
http://msdn.microsoft.com/en-us/library/ff650316.aspx
At a guess, based on the information you've given, does AutoCAD create a new instance of your object for each method call? This would explain why your instance variables are empty.
Try making the variables static and see if the data persists across method calls.
Does the AutoCAD docs have any instructions for writing these programs?
It looks like you are calling a new instance of your class, You could implement a singleton pattern to make sure you are always calling the same instance or persist the points and load them second time round.
Here's a good link for the Singleton implementation in c#, http://csharpindepth.com/Articles/General/Singleton.aspx
I was working in the Microsoft.Ink dll recently using C# and was debugging a problem (which is not related to this) I noticed, that when I was debugging it, ink objects had a strokes object, which had an ink object, which had.... etc.
This confused me, as I was under the assumption you could not do this (I come from a C++ Background)
But I ignored it, solved the problem, and moved on. Today, I run into a similar problem, as I look at a class which had a private member which was the same class as itself.
public sealed class Factory
{
private static Factory instance = new Factory();
}
How is that even possible? I can now call instance.instance.instance.instance...etc. This, as you can imagine, hurts my mortal brain, and I'm sure it can't be good on the computer either. How does the compiler deal with this? And Just how deep does the rabbit hole go?
Because it's static and therefore there is only one copy of the variable instance within the AppDomain.
What you're thinking of is this:
public class Foo
{
private Foo lol = new Foo();
}
Notice, everything here is instance, not static.
As the commenters noted (long ago), this is valid syntactically, but would result in a StackOverflowException being thrown, as the assignment requires construction, and construction creates a new assignment. One triggers the other in a cycle that ends when the call stack reaches its maximum length.
In OP's example, assignment requires construction, but the assignment is triggered by the static constructor, not the instance constructor. The static constructor only executes once within an AppDomain, in order to initialize the class' Type. It isn't triggered by instance construction, and so (in OP's example) won't result in a stack overflow.
it's not necessarily recursive by nature. think of a linked list. or a tree.
class Directory
{
string name;
Directory parentDirectory;
}
It's just allows objects of that class to have an internal reference to another object of that class.
This is a software pattern known as "Singleton".
Some people frown upon the use of the pattern for more reasons than just stated in the question but for better or for worse it is a common pattern in the .NET Framework. You will find Singleton Properties (or fields) on classes that are meant to be instantiated only once. Think of a static Instance property as a global hook upon which to hang an object.
Since this is a class, and not a struct, when you declare a field that is the class, you are only defining a reference to a class. This allows you to keep having references, provided you assign them.
In your case, you're reference allocates a new class, but it is static, so it's only going to do it one time, no matter how many classes you create. The instance constructor runs the first time Factory is used, and will call a single non-static constructor. Doing instance.instance.instance is not allowed, since instance is static. You cannot access a static variable from a member - you need to do Factory.instance.
However, you ~could~ make instance non-static, and have it be a reference to some other "Factory" class, or even a reference to this. In that case, you could chain instance.instance.instance - but it will just follow the references as long as you've set them. Everything works, no problems.
There will only ever be one instance of 'instance' because it is static. The only way you should be able to access it is by calling Factory.instance.
string text = Factory.instance.ToString(); // legal
string text2 = Factory.instance.instance.ToString(); // compiler error
I think you should ask the other way around: Why shouldn't this be possible? Factory is just a type like any type which gets resolved by the compiler.
As most of the answers here point out that this is working only because Factory is a static field, I have added the following sample. Please note that this is a very primitive sample of a chained list (you probably wouldn't implement it that way for various reasons, but I didn't come up with a better example yet). In this example, ChainedListItem is a container for an element of a single-linked list, which contains a field of the very same type to point to the next item in the list. The list has an (empty) head element and the last element is marked by having an empty _nextItem field:
public class ChainedListItem<T>
{
private ChainedListItem<T> _nextItem;
T _content;
public ChainedListItem<T> NextItem
{
get { return _nextItem; }
set { _nextItem = value; }
}
public T Content
{
get { return _content; }
set { _content = value; }
}
public ChainedListItem<T> Add(T content)
{
_nextItem = new ChainedListItem<T>();
_nextItem.Content = content;
return _nextItem;
}
public void Dump()
{
ChainedListItem<T> current = this;
while ((current = current.NextItem) != null)
{
Console.WriteLine(current._content);
}
}
}
class Program
{
static void Main(string[] args)
{
ChainedListItem<int> chainedList = new ChainedListItem<int>();
chainedList.Add(1).Add(2).Add(3);
chainedList.Dump();
}
}
The "rabbit hole" goes as deep as your stack space allows you to make another call to the constructor of the type. If you try to go deeper than that, you will get a stackoverflow exception as with any other recursion.
By the way, the code that you wrote in your answer is showing a very basic implementation of a Singleton which is actually based on having a (private) static member of the same type as the surrounding type.
And, last but not least, such constructs are also perfectly fine in C++.
It is a singleton. Meaning there is really only one instance of the class.
Is that the entire class? Typically in C# you will see a singleton like
public class SomeClass
{
static readonly SomeClass instance = new SomeClass();
public static SomeClass Instance
{
get { return instance; }
}
static SomeClass()
{
}
SomeClass()
{
}
}
I'm not sure how you would even access the instance since it is private. The only thing this would be useful for is a Singleton implementation, but if that is the case you are mission the public property exposing the instance.
This is done all the time is most OO languages. instance is a static member of Factory. There is nothing unusual about this code. It is standard Factory pattern. Do you also have a problem with code like this?
x = x + 1;
I have a class which you pass in a folder and then it goes off and processes a lot of data within the specified folder.
For instance:
MyClass myClass = new MyClass(#"C:\temp");
Now it goes off and reads say a couple of thousand files and populates the class with data.
Should I move this data out from the constructor and have it as a separate method, such as the following?
MyClass myClass = new MyClass();
myClass.LoadFromDirectory(#"C:\temp");
Maybe you should try it this way with a static method that returns an instance of the object.
var myClass = MyClass.LoadFromDirectory(#"C:\temp");
This will keep the initialization code outside of your constructor, as well as giving you that "one line" declaration you are looking for.
Going on the comment from below from the poster, by adding State an implementation could be like so:
public class MyClass
{
#region Constructors
public MyClass(string directory)
{
this.Directory = directory;
}
#endregion
#region Properties
public MyClassState State {get;private set;}
private string _directory;
public string Directory
{
get { return _directory;}
private set
{
_directory = value;
if (string.IsNullOrEmpty(value))
this.State = MyClassState.Unknown;
else
this.State = MyClassState.Initialized;
}
}
#endregion
public void LoadFromDirectory()
{
if (this.State != MyClassState.Initialized || this.State != MyClassState.Loaded)
throw new InvalidStateException();
// Do loading
this.State = MyClassState.Loaded;
}
}
public class InvalidStateException : Exception {}
public enum MyClassState
{
Unknown,
Initialized,
Loaded
}
It depends. You should evaluate the basic purpose of the class. What function does it perform?
What I usually prefer is to have a class constructor do the initialization necessary for the functioning of the class. Then I call methods on the class which can safely assume that the necessary initialization has been done.
Typically, the initalization phase should not be too intensive. An alternative way of doing the above may be:
// Instantiate the class and get ready to load data from files.
MyClass myClass = new MyClass(#"C:\temp");
// Parse the file collection and load necessary data.
myClass.PopulateData();
I agree with Ari and others - split them up.
A constructor should really do the minimum amount of work (simply initialise the object ready for use and leave it at that). By using a separate method to do the work:
It is clearer to the caller that the worker function may take a long time.
It is easy to provide several constructors to initialise the object with different information (e.g. you might be able to pass in your own class (rather than a string) that can supply the pathname. Or you could pass in an extra parameter that specifies a wildcarded filename to match, or a flag to specify if the search should recurse into subfolders).
You avoid any issues with the constructor. In the constructor the object is not fully formed, so it can be dangerous to do work - e.g. calling a virtual function inside a constructor is a very bad idea. The less code you put in the constructor the less likely it is that you'll do something "bad" by accident.
It's cleaner coding style to separate different behaviours/functions into separate methods. Keep initialisation and work separated
A split class will be easier to maintain and refactor in future.
Is this all your class does? If so, then I would say it doesn't really matter. But it is likely that you're class is actually doing more than what you have shown. Does it have any error handling, for example?
The purpose of the constructor is to construct an object. The purpose of a method is to perform an action. So my vote is for this form:
MyClass myClass = new MyClass();
myClass.LoadFromDirectory(#"C:\temp");
I think you should decide between the two approaches above ("first initialize, then execute" vs "empty init, perform with params") based on whether you plan on reusing the same object to perform the same operation on a differnt input.
if the class is only used to run the task on a fixed param, I'd go with initializing it in the constructor (making it readonly even), and then performing the task on a different method.
If you want to keep performing the the task on different params, I'd put it in the task method itself.
If all the class does is this task, I'd also consider changing it all to a static class/methods - it doesn't need to keep its internal state.
Anyway, I would never put the task itself in the constructor. As Cerebrus said, the initialization should be fast.
Unless the main purpose of your class is to perform I/O, you should probably not be performing I/O (potentially throwing an IOException) in the constructor.
Consider splitting the class in two:
interface IMyDataSource
{
// ...
}
class FileDataSource: IMyDataSource
{
public FileDataSource(string path)
{
// ...
}
}
class MyClass
{
public MyClass(IMyDataSource source)
{
// ...
}
}
IMyDataSource myDS = new FileDataSource(#"C:\temp");
MyClass myClass = new MyClass(myDS);
That way the main class can focus on managing its own state, while the data source builds the initial state from the file contents.
If that is the only resource the class works with, it'd probably be better to pass the path to the constructor. Otherwise, it would be a parameter to your class members.
My personal preference would be to use C# 3.0 initializers.
class MyClass {
public string directory;
public void Load() {
// Load files from the current directory
}
}
MyClass myClass = new MyClass{ directory = #"C:\temp" };
myClass.Load();
This has a few advantages:
Object instantiation won't have an
automatic file system side effect.
All arguments are named.
All arguments are optional (but,
of course, could throw an
exception in Load() if not defined)
You can initialize as many properties as you
want in the instantiation call
without having to overload the
constructor. For instance, options
for whether to recurse directories,
or a wildcard for filespec to search
for.
You could still have some logic
in the setter for directory to do
some stuff, but again, side effects
are usually not a good thing.
By performing file operations in a
separate procedure call, you avoid
the issue of not being able to
reference your myClass instance in
the exception handler.
I'm going to echo the "split them up" folks here. If it helps, try this:
Ask yourself, "What does this method/property/field do?"
Make it do that; no more, no less.
Applying that here, you get this:
The constructor is supposed to create the object.
Your method is supposed to load its data from the filesystem.
That seems to me to be a lot more logical than "The constructor is supposed to create the object and load its data from the filesystem.