I have an interface and class like this
public interface ICustomerEx
{
void Load(DataRow row);
}
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
Name = (string)row["name"];
Address = (string)row["address"];
}
}
Now I'm building this as a class library and add to another project as a reference.
In that project there's a class called UiCustomer that implements from the same refereced interface ICustomerEx
In this class it has its own property and load that property from its load method.
public class UiCustomer:ICustomerEx
{
public string Telephone{get;set;}
void Load(DataRow row)
{
Telephone=(string)row["tele"];
}
}
Now is there any way to implement my first class's(that build as a class library) Load method to load Ui project's properties after loading it's own properties by using like Dependency Injection.
eg.
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
Name = (string)row["name"];
Address = (string)row["address"];
//Call load methods in other places that Interface implemented
}
}
It depends what you want. Using separate classes as you have now, you'd need to dependency-inject a list of ICustomerEx objects into each Customer, but then you'd end up with a bunch of different objects each of which would have only a subset of the relevant properties. It sounds like inheritance + the template method pattern might be a better fit:
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
this.Name = (string)row["name"];
this.Address = (string)row["address"];
this.DoMoreLoading(row);
}
// this method is defined as a no-op in the base class, but it provides an extension point
// for derived classes that want to load additional properties
protected virtual void DoMoreLoading(DataRow row) { }
}
// note that now UiCustomer extends Customer (and thus still implements ICustomerEx
public class UiCustomer : Customer
{
public string Telephone { get; set; }
protected override void DoMoreLoading(DataRow row)
{
this.Telephone = (string)row["tele"];
}
}
// usage
var uiCustomer = new UiCustomer();
uiCustomer.Load(row); // populates name, addr, and telephone
To support instantiating the customer on the library side, you'll need some way to make the library aware of the UiCustomer class.
One way to do this would be to register an ICustomerEx with an IOC container and then resolve the instance using dependency injection:
// in the UI code (this is code for the Autofac IOC container):
ContainerBuilder cb = ...
cb.RegisterType<UiCustomer>().As<ICustomerEx>();
cb.RegisterType<AServiceThatNeedsACustomer>();
// in the library code
public class AServiceThatNeedsACustomer {
private readonly ICustomerEx customer;
// the customer will get injected by the IOC container
public AServiceThatNeedsACustomer(ICustomerEx customer) {
this.customer = customer;
}
}
Alternatively, you could use a factory pattern:
// in the library:
public static class CustomerFactory {
private static volatile Func<ICustomerEx> instance = () => new Customer();
public static Func<ICustomerEx> Instance { get { return instance; } set { instance = value; } }
}
// then to get a customer
var cust = CustomerFactor.Instance();
cust.Load(row);
// in the UI code:
CustomerFactory.Instance = () => new UiCustomer();
You can call the other implementations like this
In the assembly that contains the interface ICustomerEx you can add a registry-class that stores instances of ICustomerEx like this
(Note this is pseudocode to show how it could go.)
public class CustomerRegistry : ICustomerEx {
// singelton
public static final CustomerRegistry theRegistry = new CustomerRegistry();
private ArrayList<ICustomerEx> customers = new ArrayList<ICustomerEx>();
public void RegisterCustomer(ICustomerEx customer) {
customers.add(customer);
}
public void Load(DataRow row)
{
foreach(ICustomerEx customer in customers) {
customer.Load(row);
}
}
}
every implementation of ICustomerEx needs a call to the registry
CustomerRegistry.theRegistry.RegisterCustomer(new UiCustomer());
in your main customer class you use the registry to call the other loads
public class Customer:ICustomerEx
{
void Load(DataRow row)
{
CustomerRegistry.theRegistry.Load(row);
}
}
Related
I have a project involving a webshop for different kinds of products. From what I understand, if you have multiple classes that inherit from one base class, the factory design pattern is the way to go. I only have trouble deciding where to put the logic for actually deciding which factory to use.
I have created classes and factory classes for the different kinds of products like so.
public class Product
{
public int ID { get; protected set; }
public string Name { get; set; }
public ProductType Type { get; private set; }
public Product(int id)
{
ID = id;
Populate();
}
public virtual void CompleteOrder()
{
//SendMailToSupplier();
}
private void Populate()
{
//database stuff including setting the type
}
}
public class DigitalProduct : Product
{
public DigitalAsset ProductAsset { get; private set; }
public DigitalProduct(int id, DigitalAsset asset) : base(id)
{
ProductAsset = asset;
}
public override void CompleteOrder()
{
base.CompleteOrder();
//SendAssetToUser();
}
}
public class PrintProduct : Product
{
public PrintInformation Information { get; private set; }
public PrintProduct(int id, PrintInformation information) : base(id)
{
Information = information;
}
public override void CompleteOrder()
{
base.CompleteOrder();
//PreparePrintingFlle();
}
}
public abstract class ProductFactory
{
public abstract Product CreateProduct(int id);
}
public class GenericProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
return new Product(id);
}
}
public class DigitalProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
DigitalAsset asset = GetDigitalAsset(id);
return new DigitalProduct(id, asset);
}
private DigitalAsset GetDigitalAsset(int id)
{
DigitalAsset asset = new DigitalAsset();
//IO stuff
return asset;
}
}
public class PrintProductProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
PrintInformation information = GetPrintInformation(id);
return new PrintProduct(id,information);
}
private PrintInformation GetPrintInformation(int id)
{
PrintInformation information = new PrintInformation();
//database stuff
return information;
}
}
Now when an order is completed an event is triggered.
public void OrderCompleted(int orderId, List<int> productIds);
So here I have a list of int's from which I want to make product object so I can call the
CompleteOrder function on each of them. The problem is to know the type of the product I need to get the product type from the database which is filled in the populate function.
What I could do is create a function public ProductFactory GetFactory(int id) in the ProductFactory. But then the factory is can not be an abstract class.
Another option would be creating a function public static Product GetProduct(int id) in the product class. Which then first figures out which factory to use and the returns the created product.
But both of this options feel weird. Am I missing something? Or is one of these the actual way to go?
Cheers.
So skip the Populate function in the Product class. That is the duties of the factory to do. And I would go with one factory class to create all types of products. (The factory can if needed call other classes to help create the product)
Something like:
public class ProductFactory
{
public Product GetProductById(int id)
{
var dbProduct = FetchFromDb(id);
switch(dbProduct.Type)
{
case "Print"
return CreatePrintProduct(dbProduct);
case "Digital"
return CreateDigitalProduct(dbProduct);
}
}
private DigitalProduct CreateDigitalProduct(DbEntity dbProduct)
{
var product = new DigitalProduct(dbProduct.Id);
//Initialize the product
return product;
}
//You might also want a batch function to avoid calling the database for each product.
public IEnumerable<Product> GetProductByIds(IEnumerable<int> ids)
{
var dbProducts = FetchFromDb(ids);
...
}
}
Eh, just don't over think it. Design patterns should be tools you wield to create your code, if I read your question correctly, I think you are more in a state of the design pattern wielding you.
So unless the pattern helps you, do not over complicate your code with it.
That said, If you do choose to go for a pattern, your situation seems simple enough to go for Magnus's solution.
look at this example of factory method design pattern: http://jayeshtanna.azurewebsites.net/2018/11/25/factory-method-design-pattern/
I'm using Unity in with C#. I have an interface I call IConnectionStringLoader, which have two derived interfaces.
public interface IConnectionStringLoader
{
string Get();
void Write();
}
public interface IDbConnectionStringLoader : IConnectionStringLoader
{
}
public interface IMetaDataConnectionStringLoader : IConnectionStringLoader
{
}
It has only one implementation:
public class ConnectionStringLoader : IDbConnectionStringLoader, IMetaDataConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
My registration looks like this:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("DbConnection"));
The point of the interfaces is that I can inject the different interfaces in my classes and get the correct connectionstring for each implementation. But the problem is that whatever registration is done last will overwrite the previous one.
var foo = _container.Resolve<IDbConnectionStringLoader>();
var bar = _container.Resolve<IMetaDataConnectionStringLoader>();
foo.Write();
bar.Write();
Output is:
DbConnection
DbConnection
If I invert the order of the registration the output will be MetaConnection twice. So my conclusion so far is that the last registration overwrites the previous one. However, if I change the implementation to a derived class it works:
public class SomeOtherConnectionStringLoader : ConnectionStringLoader
{
public ConnectionStringLoaderImpl(string connectionStringName) : base(connectionStringName)
{
}
}
And change the registrations:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, SomeOtherConnectionStringLoader >(new InjectionConstructor("DbConnection"));
Now everything works, but I don't understand why. I've tried different lifetimemanagers, but with the same result. I thought Unity would try to create an instance of ConnectionStringLoader with the "correct" injectionparameter based on the interface, but there's seems to be some other logic at play here.
Any suggestions why the registrations overwrite each other?
Honestly speaking, the way you are using the interfaces looks strange to me because there are two interfaces implemented only by the same class. I would find more natural to follow the next approach using registration names:
// If it is a loader the Write method makes no sense (IConnectionStringRepository?)
public interface IConnectionStringLoader
{
string Get();
void Write();
}
public class ConnectionStringLoader : IConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
Registrations:
container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Database", new InjectionConstructor("MetaConnection"));
container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Metadata", new InjectionConstructor("DbConnection"));
Resolutions:
var foo = _container.Resolve<IConnectionStringLoader>("Database");
var bar = _container.Resolve<IConnectionStringLoader>("Metadata");
foo.Write();
bar.Write();
I'm not familiar with Unity. But it seems they are mapping to same instance. So you should change lifetime of ConnectionStringLoader (Per dependency).
If you will not share instance, why do you put all things in one class ? ConnectionStringLoader Methods = IDbConnectionStringLoader methods + IMetaDataConnectionStringLoader methods.
When you resolve IDbConnectionStringLoader it will not use IMetaDataConnectionStringLoader methods which is already in instance (vice versa it's true).
Crating two different derived class is better at this point:
Abstract class:
public abstract class ConnectionStringLoader : IConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
Derived Classes:
public sealed class DbConnectionStringLoader : ConnectionStringLoader, IDbConnectionStringLoader
{
public DbConnectionStringLoader(string connectionStringName):base(connectionStringName)
{
}
//Implement methods here just belongs to IDbConnectionStringLoader
}
public sealed class MetaDataConnectionStringLoader : ConnectionStringLoader, IMetaDataConnectionStringLoader
{
public MetaDataConnectionStringLoader(string connectionStringName):base(connectionStringName)
{
}
//Implement methods here just belongs to IMetaDataConnectionStringLoader
}
Surprisingly it does call ConnectionStringLoader ctor twice, but with same injection member. If you look at container.Registrations, there are indeed two registrations so it is not override one with other. I did look at implementation of RegisterType, but didn't get my head around it.
One alternative is to name your registrations, not sure if it fits into your overall unity bootstrap strategy.
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>("bar", new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>("foo", new InjectionConstructor("DbConnection"));
var foo = container.Resolve<IDbConnectionStringLoader>("foo");
var bar = container.Resolve<IMetaDataConnectionStringLoader>("bar");
I often use
using (var context = new SomeDataContext(SomeDataContext.ConnectionString))
{
...
}
where
abstract class DataContextBase: DataContext { ... }
partial class SomeDataContext: DataContextBase
{
public const string DatabaseFile = "blablabla.mdf";
public static readonly string ConnectionString = string.Format(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFile);
}
Question: Is it possible to hide creation of SomeDataContext instance and ConnectionString deep into DataContextBase?
I want to define only file name in inherited classes
partial class SomeDataContext: DataContextBase
{
public const string DatabaseFile = "blablabla.mdf";
}
and to be able to create instances like this
var context = SomeDataContext.PropertyInBaseClassWhichCreatesInstanceOfInheritedClass;
P.S.: I add at first of how I tried to overcome the problem (without success tbh), but then I deleted it (I was making this post over hour!), because it makes question too noisy. It may looks easy at first, until you (or is it only me?) try to solve it. I tagged it dbml because of specific to DataContext things: you can't use singleton, etc.
Unfortunately, there isn't some sort of virtual static, and if you call SomeDataContext.StaticPropertyInBaseClass, it compiles to the same as DataContextBase.StaticPropertyInBaseClass. I think the best you can do is something like this:
// upside: simple SomeDataContext.Instance for external users
// downside: more code in SomeDataContext
partial class SomeDataContext : DataContextBase
{
private const string DatabaseFile = "blablabla.mdf";
public static SomeDataContext Instance
{
get
{
return new SomeDataContext(GetConnectionString(DatabaseFile));
}
}
}
abstract class DataContextBase
{
protected static string GetConnectionString(string databaseFile)
{
return string.Format(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", databaseFile);
}
}
// e.g. using (var context = SomeDataContext.Instance)
Or
// upside: just one line in child class
// downside: a little harder for external callers, with a little less type safety
// downside: as written, requires child class to have parameterless constructor
partial class SomeDataContext : DataContextBase
{
protected override string DatabaseFileInternal { get { return "blablabla.mdf"; } }
}
abstract class DataContextBase
{
protected abstract string DatabaseFileInternal { get; }
private string ConnectionString
{
get
{
return string.Format(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFileInternal);
}
}
public static T GetInstance<T>() where T : DataContextBase, new()
{
using (var tInst = new T())
return (T)Activator.CreateInstance(typeof(T), tInst.ConnectionString);
}
}
// e.g. using (var context = DataContextBase.GetInstance<SomeDataContext>())
I have two versions of a factory class designed based on the article
http://www.oodesign.com/factory-pattern.html
public abstract class Employee
{
public string Name { get; set; }
protected string Role { get; set; }
public abstract string GetRole();
}
public class Manager : Employee
{
public Manager()
{
Role = "MGR";
}
public override string GetRole()
{
return this.Role;
}
}
Version 1: Simple, Violates Open Close Principle
Need to change SimpleEmployeeFactory every time, when I add a new concrete class
public class SimpleEmployeeFactory
{
public static Employee GetEmployee(int typeId)
{
switch (typeId)
{
case 1:
return new Manager();
case 2:
return new TechnicalLead();
default:
return null; //if the id doesn't have any
}
}
}
Version 2:
Refactored Factory, still needs a Concrete Class creation, before we use factory call
public abstract class Employee
{
public string Name { get; set; }
protected string Role { get; set; }
public abstract string GetRole();
public abstract Employee createEmployee();
}
public class ChiefTechnologyOfficer : Employee
{
public ChiefTechnologyOfficer()
{
this.Role = "CTO";
}
static ChiefTechnologyOfficer()
{
RefactoredFactory.Instance.registerEmployee(5, new ChiefTechnologyOfficer());
}
public override string GetRole()
{
return this.Role;
}
public override Employee createEmployee()
{
return new ChiefTechnologyOfficer();
}
}
Factory
class RefactoredFactory
{
private static readonly RefactoredFactory instance = new RefactoredFactory();
static RefactoredFactory()
{
}
private RefactoredFactory()
{
}
public static RefactoredFactory Instance
{
get
{
return instance;
}
}
private Dictionary<int, Employee> registeredEmployees = new Dictionary<int, Employee>();
public void registerEmployee(int typeId, Employee employeeInst)
{
registeredEmployees.Add(typeId, employeeInst);
}
public Employee createEmployee(int typeId)
{
return ((Employee)registeredEmployees[typeId]).createEmployee();
}
}
Client
Employee emp = SimpleEmployeeFactory.GetEmployee(1);
Activator.CreateInstance(typeof(ChiefTechnologyOfficer)); //Avoid
Employee empFNoR = RefactoredFactory.Instance.createEmployee(5);
You can see Activator.CreateInstance(typeof(ChiefTechnologyOfficer)) call to make the concrete classes to register themselves with the Factory. Otherwise we cant retrieve the object
Is there a way to create a Factory class with out violating OCP principle & with out creating an object like the one I used in RefactoredFactory class?
It looks like the typeId suffers from Feature Envy. Instead, define a polymorphic type to capture the type; e.g. an interface:
public interface IEmployeeType
{
Employee Create()
}
Now you can define e.g. a ManagerType, and a TechnicalLeadType, etc. Example:
public class ManagerType : IEmployeeType
{
public Employee Create()
{
return new Manager();
}
}
This is essentially an Abstract Factory, and it has the advantage that you can always create a new implementation when you need to create a new sub-type.
If you're at the boundary of a system, and must translate a primitive value like an integer to a polymorphic value, you can use one of the Role Hint patterns - particularly Metadata, Role Interface, or (my favourite) Partial Type Name.
Client
Given an IEmployeeType instance employeeType, a client would simply go:
Employee emp = employeeType.Create();
Thala,
Instead of using static constructor,register method to populate dictionary of Types.
You can use config based solution like .net DbProviderFactory, to register all types.
<EmployeeFactories>
<add name="manger" type="Manager, EmployeeAssmbly" />
..
</EmployeeFactories>
I have a need where I have to add some new fields to an existing class along with all its existing fields/attributes.
So whenever my derived class is filled by DAL, I will be filling all fields of base class as well. Currently, I am doing it like this but not sure this is the right way ? Please give me an example. Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
public class Employee
{
private int _id;
private int _name;
public int ID
{
set { _id=value;}
get { return _id;}
}
public int Name
{
set { _name=value;}
get { return _name;}
}
protected void SetName ()
{
_name=value;
}
protected void SetID()
{
_id=value;
}
}
public class EmployeeWithDepartmentName:Employee
{
private string _deptName;
public string DeptName
{
set { _deptName=value; }
}
public setBaseEmpName()
{
base.SetName();
}
public setBaseID()
{
base.SetID();
}
}
Everything in a base class can automagically be accessed from derived classes without doiing anything, just use the property/method name directly.
public class MyBase
{
public string UserName {get;set;}
}
public class MyClass : MyBase
{
public void DoSomething()
{
Console.WriteLine("UserName: {0}", UserName);
UserName = "Anders";
}
}
You can also do this:
MyClass myClass = new MyClass();
myClass.UserName = "Rune";
Protected means that only derived classes can access the property/method. Public means that everyone can access the properties/methods.
Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
It's not two objects, it's one object created from two different classes (that's how inheritance works).
Read this article about inheritance: http://www.csharp-station.com/Tutorials/lesson08.aspx