How to manage instances and class instantiations therein - c#

Let's say I have two classes.
One class User which has a lot of instances and one AccountInterface which is handling Database/File System Queries and might be accessed by every user.
Lets say, User looks like this:
public class User
{
public User(string uID)
{
this.UID = uID;
}
AccountInterface AccountInterface = new AccountInterface();
public string UID {get;private set;}
private string _Alias;
public string Alias
{
get
{
if (Alias.IsNullOrEmpty())
this._Alias = AccountInterface.GetAlias(this.UID);
return this._Alias;
}
set
{
if (this._Alias == value) return;
AccountInterface.UpdateAlias(this.UID,value);
this._Alias = value;
}
}
}
From my Understanding, each new instance of User will create a new instance of AccountInterface. Could this impose negative effects? Is this the proper way to handle multiple Instances?
I have had many simillar encounters in my projects and always ask myself if this is how things are done. For example, I have a program reading from a ticket system. After all I am able to modify/edit each instance of a ticket with someTicket.Description = "new Description" or someTicket.WriteComment("Some comment")
I wonder if it's better to build all logic into the interface class and work like
TicketInterface.WriteComment(someTicket, "Some Comment") or TicketInterface.ChangeDescription(someTicket, "some description").
I find the first Method more clean and intuitive as I can have general code in the Interface (Such as TicketInterface.GetAllTickets() ) while having instance specific code such as someTicket.WriteComment("Some comment") within the Instance. I believe this might cause negative impact, for example by opening a new Database Connection for each new Instance of an Object.

As AccountInterface is managing tasks which are not required to be bound to another class instance you could make AccountInterface a static class or implement the singleton pattern in an static context.
public static class AccountInterface{
public static WriteToFile(string output){...}
public static WriteToDb(object obj){...}
}
Or
public static class AccountContext{
private static AccountInterface _interface;
public static AccountInterface Interface {
get { return _interface; }
set
{
if(_interface == null) _interface = value;
}
}

From my Understanding, each new instance of User will create a new instance of AccountInterface. Could this impose negative effects? Is this the proper way to handle multiple Instances?
Maybe? It is perfectly reasonable for a object to instantiate other objects on constructions. One thing that seem odd is that AccountInterface does not take any parameters, in some cases this is perfectly fine, but in some cases it suggests that the class and the methods it contain should be 'static'.
If AccountInterface has any dependencies it might be better to use dependency injection. I.e.
public User(string uID, AccountInterface accountInterface)
{
this.UID = uID;
this.accountInterface = accountInterface;
}
AccountInterface AccountInterface;
And let a dependency injection framework take care of resolving any dependencies. If you have any static dependencies this can help avoid these, since it lets all components in the DI container share a object, instead of sharing the same object in the entire program.
In your ticket example, a typical design would use a ticket repository that is responsible for loading and saving tickets. Once a ticket has been loaded it can be modified using the properties and methods on the ticket, and once done it would be saved back to the repository. So GetAllTickets would be part of the repository class, but WriteComment would be part of the ticket class.
When accessing resources remotely it can be somewhat more common with a interface like TicketInterface.WriteComment(ticketId, comment) since that would be very easy to translate to a webrequest, and it can avoid downloading a somewhat large objects when you do not need all the data it contain.

Related

Storing/Saving a Method and later re-calling it

What I am currently atempting to make is an inventory system. I wonder if I can store the current method and then open the inventory, and when I am done there, reopen/recall the previus method that ran.
You haven't provided very much information but I can tell you don't want to store a method, you want to store an object.
An object is an instance of a class. Depending on the kind of class you have you can either create multiple instances of a class and instantiate them multiple times across your application. Or alternatively you can create single instances of an object that you use throughout your entire application/game.
From the sounds of it, you want to use a singleton class that retains the current values of the user's inventory. So if you interact with the inventory class in one part of your program, you would like to then view and interact with the same previously modified values stored within the singleton from another part of your program.
I can't give you a concrete answer to your problem, but a possible Singleton class for your use case would look something like this;
public sealed class Inventory
{
private static readonly Inventoryinstance = new Inventory();
// Explicit static constructor to tell C# compiler
// not to mark type as before field init
static Inventory()
{
}
private Inventory()
{
// optionally, pre-populate with data stored in database when constructed
}
public static Inventory Instance
{
get
{
return instance;
}
}
public List<InventoryItem> InventoryItems { get; set; } = new List<InventoryItem>();
public void AddItemToInventory(InventoryItem item) {
InventoryItems.Add(item);
}
public void RemoveItemFromInventory(InventoryItem item) {
InventoryItems.Remove(item);
}
}
You can use this site for reference - https://csharpindepth.com/articles/singleton
If you have an application that utilises DI, you can create singleton instances that are injectable into your other app classes. This is a better way of handling singletons as they are handled by an IoC system rather than being made static for the entire application to access.

How to get/set a property of an interface that is not always implemented

What is a good (object oriented) way of setting a property of a class which implements an interface, when that property doesn't always exist in all classes that implement that same interface?
e.g.
Let's say I have an interface
public interface IDataRepository {
public DataStructure GetData(); // DataStructure is an arbitrary class, doesn't matter for this example
}
Now I also have two classes that inherit from this
public class DatabaseRepository : IDataRepository {
public DataStructure GetData()
{
// get data from database
}
}
and
public class FileRepository : IDataRepository {
public string WorkingFolder { get; set; }
public DataStructure GetData() {
// get data from files
}
}
Now my client method doesn't necessarily know what the repository is but here's what I want to do...
private DataStructure ReadData(IDataRepository repository)
{
repository.WorkingFolder = #"C:\Data"; // What is the best way of doing this?
return repository.GetData();
}
obviously the above code won't work and I could do...
if (repository is FileRepository) {
((FileRepository)repository).WorkingFolder = #"C:\Data";
}
or add WorkingFolder as a property of the interface (and therefore all the classes that implement it) even though in most cases it's irrelevant.
but both of these (esp. the first one) seem very inelegant and not very object oriented. What is the oop way of doing this kind of thing?
Edit
The obvious question is if the method doesn't know what repository is, how can it know the correct value for WorkingFolder... But the above is an over-simplification of what I'm trying to do, so let's just say it can find out...
Apparently your ReadData method can't actually accept any type of repository. It is only able to handle a FileRepository. That's what it expects, and that's what it needs to do its job. Given that, that's what it should actually accept as its parameter, rather than an interface that doesn't actually provide a contract that is sufficient for it to do its job.
The entire point of having an interface is so that anyone using that interface can use it without caring what the implementation is. So if you do want to use the interface you need to include enough information in the interface's definition such that it provides every operation that anyone using the interface needs, otherwise you're better off just not using it at all (at least for that specific operation).
As for the specific example given, you should probably just be providing an already configured repository, that has whatever values it needs in order to allow this method to do its work, as a parameter. It doesn't make sense for a method that's reading a value from an arbitrary repository to be configuring that repository at all. That is, if it really is reading something from an arbitrary repository.
As others have said in the comments, you should initialise these properties in the constructor. This is where you know what type you're creating, so you also know what arguments its constructor requires / can set those there.
Once you've initialised the object, you can just pass it around / have anything using that class operate against its interface.
Example:
public void Main(string[] args)
{
var myRepo = new FileRepository(args[0]); //Here's where we set the working directory
var myThing = new Thing();
var data = myThing.ReadData(myRepo);// of course, the current implementation means you could just call `myRepo.GetData()` directly, since ReadData just passes out the same response; but presumably that method adds some additional value..
Console.WriteLine(data.ToString());
}
Supporting Code
public class DatabaseRepository : IDataRepository {
DbConnection connection; //you may want a connection string or something else; going with this type just to illustrate that this constructor uses a different type to the FileRepo's
public DatabaseRepository(DbConnection connection)
{
this.connection = connection;
}
public DataStructure GetData()
{
// get data from database
}
}
public class FileRepository : IDataRepository {
public string WorkingFolder { get; set; } //Do you need set? Generally best to keep it constant after initialisation unless there's good reason to change it
public FileRepository (string workingFolder)
{
this.WorkingFolder = workingFolder;
}
public DataStructure GetData() {
// get data from files
}
}
How do I call the code that creates the class
i.e. maybe you've implemented a really basic factory pattern like so, and want to know how to provide arguments:
public class DataRepositoryFactory
{
Type baseType = typeof(IDataRepository);
IDictionary<string, Type> typeMap = new Dictionary<string, Type>() {
{"File", typeof(FileRepository) }
,{"Db", typeof(DatabaseRepository) }
}
public void RegisterType(string typeName, Type type)
{
if (!baseType.IsAssignableFrom(type)) throw new ArgumentException(nameof(type));
typeMap.Add(typeName, type);
}
public IDataRepository GetDataRepository(string typeName)
{
return (IDataRepository)Activator.CreateInstance(typeMap[typeName]);
}
}
(For a more complex example of a factory, see https://web.archive.org/web/20140414013728/http://tranxcoder.wordpress.com/2008/07/11/a-generic-factory-in-c).
I.e. in this scenario, when you call the factory you know what type you want, but you're only giving it a string to name/identify that class. You could add a params object[] args to your GetDataRepository method, allowing you to call it like so:
var myRepo = myDataRepositoryFactory.GetDataRepository("File", "c:\somewhere\something.dat");
That's a good approach / is actually what's used on the linked example above. However, it means that your call to this code differs for different types; since if we use variables instead of hardcoded values as in the above example we can't simply do the below, since myRepoType could be set to "Db", whilst "myFilePath" would be a string:
var myRepo = myDataRepositoryFactory.GetDataRepository(myRepoType, myFilePath);
That's fixable by calling:
var myRepo = myDataRepositoryFactory.GetDataRepository(myRepoType, myArgs);
i.e. where myArgs is an object[], giving all of the values required in the desired order to initialise the type. The piece to populate object[] with the required values could then take place at the same point at which you decided you wanted the type to be a file repo vs database repo. However, this approach isn't that clean / casting to and from objects stops you from getting help from the compiler.
So how do I improve things?
There are a few options. One is to replace the need to use object[] by instead creating a type to hold your arguments. e.g.
public interface IDataRepositoryConfiguration
{
//nothing required; this is just so we've got a common base class
}
public class FileRepositoryConfiguration: IDataRepositoryConfiguration
{
public string WorkingFolder {get;set;}
}
public class FileRepository : IDataRepository {
public FileRepository (IDataRepositoryConfiguration configuration)
{
var config = configuration as FileRepositoryConfiguration;
if (config == null) throw new ArgumentException(nameof(configuration)); //improve by having different errors for null config vs config of unsupported type
this.WorkingFolder = config.WorkingFolder;
}
//...
}
This still has some issues; i.e. we may pass a DatabaseRepositoryConfiguration as our IRepositoryConfiguration when creating a FileRepository, in which case we'd get the AgumentNullException at runtime; but this does avoid issues should parameters change order, and makes it less of a headache to code / debug.
Could it be further improved?
Dependency Injection offers one solution. This could be used along the lines of the code below (i.e. you create instances of each of your classes, providing the required arguments, and give each instance a name, so that you can later fetch that instantiation. Exactly what that code looks like would depend on the dependency injection library you used:
//setting up your repositories
var container = new Container();
container.Configure(config =>
{
// Register stuff in container, using the StructureMap APIs...
config.For<IDataRepository>().Add(new FileRepository("\\server\share\customers")).Named("customers");
config.For<IDataRepository>().Add(new FileRepository("\\server\share\invoices")).Named("invoices");
config.For<IDataRepository>().Add(new DatabaseRepository(new DbConnection(configurationString))).Named("persist");
config.For<IDataRepository>().Use("persist"); // Optionally set a default
config.Populate(services);
});
//then later when you need to use it...
public DataStructure ImportCustomers(IContainer container)
{
var customerRepo = container.GetInstance<IDataRepository>("customers");
return customerRepo.GetData();
}
I'm sure there are many other approaches, and exactly what approach to use depends on how your program will operate. Hopefully the above is enough to get you past your current problem; but if you find you're still struggling please post a new question with more detail / saying where you're still having issues having considered these points.
If possible, I'd just put the value for that property in the constructor or create a subinterface, like others suggested.
If it's not possible, C# 7.X (don't remember the exact minor version) has a nice code structure for conditional casting:
IDataRepository repo = new FileRepository();
if (repo is FileRepository fileRepo)
{
fileRepo.WorkingFolder = "some dir";
}
However in your case, you should probably rethink your architecture and always pass (or even better always create) a repository object which is ready to be used.
a) Put it into the Inferface definitions. Deal with any "NotImplemented" Exceptions. You always have to expect those with Interfaces anyway.
For example, IEnumerable has a Reset() function. But in most cases it is not implemented. It is not even supposed to be implemented in most cases. Afaik it is only there for Backwards Compatabilty with some old COM stuff.
b) make a sub-interface just for the property
c) Verify the Interface is properly implemented via is checks (throw exceptions thows if nessesary, like Array.Sort will throw a InvalidOperation one), generic constraints, proper argument types and the like.

what is the correct object orientated way to get a list of custom objects

Lets say I have a user object in an external class. I'd then like to get all users.
I've read elsewhere that static methods should tend to be avoided. so calling something along the lines of List<User> usrs = User.GetAllUsers() should be avoided.
Would the best practice therefore be to do
User u = new User();
List<User> usrs = u.GetAllUsers();
it seems silly to have to create a new object and putting it in memory for the sake of calling a whole new list of objects altogether.
Usually you would have something like a UserRepository which manages your User objects and takes care of adding, deleting, searching etc. your users.
From there you would get a list of your users. Something like:
class UserRepository
{
// if you don't want to expose properties but only access them via method calls...
private List<User> Users { get; }
public UserRepository()
{
// get Users from Database or any other source...
Users = db.Users;
}
public List<User> GetAllUsers()
{
return Users;
}
public void AddUser(User u)
{
Users.Add(u);
}
}
And in your app you'd do something like this:
var userRep = new UserRepository();
var users = userRep.GetAllUsers();
You could argue about making the repository a static class if you'll just have one.
There is absolutely no reason to avoid static methods by default. Their purpose is to expose methods that can act on their own and don't need any other object data from the same logical class.
Microsoft uses static methods a lot, for example in the System.Math namespace:
https://msdn.microsoft.com/en-us/library/system.math.aspx
In your example, GetAllUsers() can be made static if you do not plan to add extra fields or methods to this collection of users in the future. If you do want this, it might be better to create a UserCollection class which represents a list of users.
public class UserCollection : Collection<User>
{
public IEnumerable GetAll()
{
return this.AsEnumerable();
}
public void MyFutureMethod()
{
//something you might want to do later on :-)
}
}
I've read elsewhere that static methods should tend to be avoided.
Static methods are not bad per se. There are many valid use cases, such as mathematical helper functions or static factories.
However, stateful static methods may be problematic. These are essentially just global variables or singletons in disguise – with all their associated problems. They are also difficult to test.

C# bank example - class for customers - what for withdrawls, deposits, etc

I'm learning C# and am trying to get my head around when to use classes and when not to.
If I was writing an app for a bank, I know I would use classes for customers which would include their name, account number, balance, etc. Would I use a static class for the methods that would deposit into their account, withdraw, change their address, etc since I only need to write them once?
Also, what would I use to keep track of every customer object? Having 2,000 Customers:
exampleName = new Customer();
in my code doesn't seem right. I'm not at the point of learning database's yet and am just learning classes.
Having a database would be ideal, but in the mean time you could use an IEnumerable to hold your Customer objects, like this:
List<Customer> myCustomers = new List<Customer>();
myCustomers.Add(new Customer {Name = "Bob", Address = "123 Anywhere St." });
Then you can just pass the list around where needed.
Typically you will then have a property on the Customer class that holds the accounts:
public class Customer
{
public Customer()
{
_accounts = new List<Account>();
}
public List<Account> Accounts
{
get { return _accounts; }
set { _accounts = value; }
}
private List<Account> _accounts;
}
And so on. Note that I'm keeping this simple and doing things the more long winded and descriptive way as you are a beginner.
Using lists of items in this way is a good way to start because you will natuarlly use these when you get to using a database; you will retrieve result sets from the database and then translate those result sets into lists of business objects.
As for using static methods to do business logic like adjusting balances, changing addresses, etc., for you at this stage it doesn't matter. If you are using tools like Resharper it will nag you with suggestions like that, but in your case you can safely ignore that particular one. What you should look for is keeping everything as self contained as possible, avoid leakage of data and leakage of responsibilities between objects - this is just good coding discipline and a good way to prevent bugs that are caused by loose coding.
Once you've got your functionality laid down and working, you may have a desire to move some functionality into static 'helper' style classes. This is absolutely fine, but do be careful - helper classes are fantastic and everything but can quickly turn into an anti-pattern if you don't maintain that coding discipline.
You don't need to use a static class, or static methods, in order to only write the methods once. It may or may not make sense to do so, but this is a perfectly valid way to write the methods without repeating yourself:
public class Customer
{
//properties, constructors, etc.
public virtual void Deposit(decimal amount) { }
public virtual void Withdraw(decimal amount) { }
//etc
}
This also allows you to make use of polymorphism, e.g.
public class BusinessCustomer : Customer
{
public override void Deposit(decimal amount) { //some other implementation }
}
Static classes are used when you aren't going to instantiate objects. You get one "instance" of that class - you can't do things like:
MyStaticClass m = new MyStaticClass();
m.SomeFunc();
when you've got a static class. Instead you'd use it by using the class name itself. Something like:
MyStaticClass.SomeFunc();
As to what would you use to keep track of every Customer object? You could use some sort of collection to hold these. Granted, in a real system there'd be some sort of persistence piece, likely a database, to hold the data. But you could just make something like:
IEnumerable<Customer> Customers = new List<Customer>();
And then add your customers to that list
Customers.Add(new Customer() { ... });
Back to the question about static methods...
So, the deal here is that you're not going to be referencing instance members in a static method, so you wouldn't use static methods to update a particular Customer's address. Assuming your Customer class looked like:
public class Customer
{
public string Address { get; set; }
}
You couldn't use a static method like
public static void SetAddress()
because each Customer (presumably) has a different address. You couldn't access the customer's address there because it isn't static. Get that? Instead, you'd use a static method if you were wanting to do something that didn't need to deal with instance data. I use static methods for things like utility functions.
public static double ComputeSomething(double someVal) { ... }
Here, the ComputeSomething function can be called by anybody like:
var result = MyStaticClass.ComputeSomething(3.15);
The takeaway here is that static classes aren't used to instantiate objects, rather they are used really as a convenient container to hold functions. Static functions are ones that can be on a non-static class but can't access any of the instance data.
One place where a static function would be used would be for the Singleton pattern. You make the constructor non-public so folks can't call it, and instead provide a static method on the class to return the one and only instance of the class. Something like:
public class MySingleton
{
private static MySingleton instance;
private MySingleton() {}
public static MySingleton Instance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
}
what for withdrawls, deposits, etc
Those would be called Transactions.
This is meant to be in addition to the other answers. This is example of polymorphism with interfaces.
public interface IDeposit {
void Deposit(decimal amount);
}
public interface IWithdraw {
void Withdraw(decimal amount);
}
public class Customer : IDeposit, IWithdraw {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
public void Withdraw(decimal amount) { throw new NotImplementedException(); }
}
public class DepositOnlyATM : IDeposit {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
}
Keeps concepts separate, and allows for implementing multiple interfaces, or just one. With class inheritance approaches you only get one, and you get all of it. Inevitably you end up with spaghetti in my experience because sub-classes want some of the behavior, but not all of it.
I would recommend instead of getting into the implementation details right away that you first write down some simple user stories for your bank example. For instance
As a customer I would like to open a new account so that I can make deposits and withdrawls
Just in that requirement, we can envision a couple of classes (customer and account). From there just functionally decompose what the customer should do and what the account should do.
I've found that the book "The Object Oriented Thought Process" is a good read and will help answer some of the questions as to "when do I do this vs. that".
Good luck and have fun!

Dependency Injection for objects that require parameters

All of our reports are created from object graphs that are translated from our domain objects. To enable this, we have a Translator class for each report, and have been using Dependency Injection for passing in dependencies.
This worked great, and would yield nice classes structured like this:
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc)
{
_empSvc = empSvc;
_paySvc = paySvc;
}
public Check CreateCheck()
{
//do the translation...
}
}
However, in some cases the mapping has many different grouping options. As a result, the c-tor would turn into a mix of class dependencies and parameters.
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc
, bool doTranslateStubData
, bool doAttachLogo)
{
_empSvc = empSvc;
_paySvc = paySvc;
_doTranslateStubData = doTranslateStubData;
_doAttachLogo = doAttachLogo;
}
public Check CreateCheck()
{
//do the translation...
}
}
Now, we can still test it, but it no longer really works with an IoC container, at least in a clean fashion. Plus, we can no longer call the CreateCheck twice if the settings are different for each check.
While I recognize it's a problem, I don't necessarily see the right solution. It seems kind of strange to create a Factory for each class ... or is this the best way?
Shot in the dark here, but could you move those parameters to the method instead?
In other words:
public Check CreateCheck(bool doTranslateStubData, bool doAttachLogo)
{
//do the translation...
}
Do those parameters have to be passed in via the constructor?
(Note - if your response to this is "there are too many methods for that to be practical", then part of the problem may be that the abstraction is too coarse).
Another option (it's really hard to say without understanding the domain model and injection patterns) would be to introduce a parameter object that is itself managed by the injector:
public interface ICheckConfiguration
{
bool AttachLogo { get; }
bool TranslateStubData { get; }
}
Then inject this with the constructor:
public CheckTranslator (IEmployeeService empSvc, IPaycheckService paySvc,
ICheckConfiguration config)
{
// etc.
}
This should be enough. You can then create a concrete CheckConfiguration class that takes those two bool properties in its constructor, and configure your container to create different instances of the parameter object (interface) based on a higher-level DI parameter.
The last thing I think I should mention is that just because you're using DI doesn't mean that everything has to be managed by the container. It's not such a bad thing to create CheckTranslator objects in an ad-hoc fashion if there's only one kind of "translator". As long as the translator still depends on abstractions, which it does here, then maybe you shouldn't be injecting it at all, just let higher-level DI-enabled classes create them ad-hoc.

Categories