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>())
Related
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 have an inheritance tree with a bunch of different classes. Each of these classes has some static properties that I need acces to from time to time. Sometimes I need the property of a particular class, and sometimes I need the property of the specific class some polymorphic instance turns out to be.
This would be easy in, say, Java (I think). Just make a bunch of static fields (can these be overriden? I'm not sure). But in C#, non-static fields can ONLY be accessed via an instance (naturally), and static fields can ONLY be accessed via their corresponding class (unnaturally).
And, you can't "overload" by, er, staticity. If a class has a static and a non static Foo, doing instance.Foo fails because it is unclear to the compiler which Foo you're referring to even though it's impossible you're referring to the static one since it's disallowed.
Ok, I'll provide some code. Say I have this:
class Base
{
public static readonly string Property = "Base";
}
class Child1 : Base
{
public static readonly new string Property = "Child 1";
}
class Child2 : Base
{
public static readonly new string Property = "Child 2";
}
And then, somewhere:
public void SomeMethod(Base instance)
{
System.Console.WriteLine(instance.Property); // This doesn't work.
}
And somewhere else:
public void SomeOtherMethod()
{
System.Console.WriteLine(Child2.Property);
}
I want something like that, that actually works.
As Peter Duniho said, this can be done with reflection.
For example, these can be defined within the base class:
public const string Property = "Base";
public virtual string InstanceProperty
{
get
{
return (string)this.GetType()
.GetField("Property", BindingFlags.Public | BindingFlags.Static)
.GetValue(null);
}
}
And then each derived class just has to redefine Property using the new keyword.
I think the best you'll do in C# is something like this:
public class BaseClass
{
public virtual string InstanceProperty
{
get { return StaticProperty; }
}
public static string StaticProperty
{
get { return "BaseClass"; }
}
}
public class Derived1Base : BaseClass
{
public override string InstanceProperty
{
get { return StaticProperty; }
}
public new static string StaticProperty
{
get { return "Derived1Base"; }
}
}
public class Derived1Derived1Base : Derived1Base
{
}
public class Derived2Base : BaseClass
{
public override string InstanceProperty
{
get { return StaticProperty; }
}
public new static string StaticProperty
{
get { return "Derived2Base"; }
}
}
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);
}
}
Consider the following very basic C# code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
for (int i = 1; i <= 100; i++)
{
int num = random.Next(1000);
string it_type;
if (num == 666)
{
System.Console.Write("Antichrist/satanistic trips get. Enjoy! ");
JonSkeet technician = new JonSkeet(); // Needs more Super::$tatic
technician.setup();
it_type = technician.getITType();
}
else
{
Whisperity technician = new Whisperity();
technician.setup();
it_type = technician.getITType();
}
System.Console.WriteLine(it_type + "... Prepare for next iteration.");
}
System.Console.ReadLine();
}
}
abstract public class ITTechnician
{
protected string itt_type = "Noname person.";
protected bool isJonSkeet = false;
public string getITType()
{
return this.itt_type;
}
abstract public void setup();
}
public class JonSkeet : ITTechnician
{
public override void setup()
{
this.itt_type = "Jon Skeet";
this.isJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
public override void setup()
{
this.itt_type = "Whisperity";
this.isJonSkeet = false;
}
}
}
How would I be able to set up a constructor in a way that the abstract class (abstract public void?) would require it and that I don't have to call technician.setup(); because the constructor takes care of setting the two internal variables. If I call the class functions the same name as the class itself, I get the following error:
Error 1 'Whisperity': member names cannot be the same as their enclosing
Also, my other question would be about optimization. Is there a way to define technician outside the if construct so something like the following could be executed: (This would omit having the classType technician = new classType(); lines twice, or is it unbypassable in C#?)
string it_type;
// Register 'technician' as a variable here.
if (num = 666)
{
technician = new JonSkeet();
}
else
{
technician = new Whisperity();
}
it_type = technician.getITType();
System.Console.WriteLine(it_type + "...");
Answer to your Question
You can provide a constructor with parameters in the abstract class.
abstract public class ITTechnician
{
public ITTechnician(string itt_type, bool isJonSkeet)
{
this.itt_type = itt_type;
this.isJonSkeet = isJonSkeet;
}
}
To construct a JonSkeet (if only it were so easy!)
JonSkeet jon = new JonSkeet("Jon Skeet", true);
Advice on Class Design
On a side note, I know this is a sample question, but you are not using object orientation well if a base class holds information that would differentiate classes that inherit from it.
Specifically this design would lead you to do things like
ITTechnician itt = GetSomeInstance();
if (itt.IsJonSkeet)
{
BehaviorA();
else
{
BehaviorB();
}
It is far cleaner to do something like
abstract public class ITTechnician
{
public abstract void Behavior();
// ...
}
public class JonSkeet
{
public override Behavior()
{
// Do awesome things
}
}
which allows the above code to be written as
ITTechnician itt = GetSomeInstance();
itt.Behavior();
How would I be able to set up a constructor in a way that the abstract
class would require it and that I don't have to call
technician.setup()
You don't need construct your logic to force the behavior of abstract class, but vice versa. Abstract class defines a stuf that has to be followed by the child.
If you create a simple parametless ctor in abstract class, which initializes the variables you need, whenever the child object will be constructed, the default ctor of abstract will be called before, so intialization will be executed.
To be more clear:
public class Child : Base
{
public Child(int x){
"Child".Dump();
}
}
public abstract class Base
{
public Base() {
//INIT VARIABLES HERE
"Base".Dump();
}
}
using these constructs like
vaar ch = new Child(); produces the result
"Base"
"Child"
If this is not what you're asking for, please clarify.
To discover a type at runtime, use GetType(). There's no need to create your own type string field.
The only thing that varies other than the intrinsic type in your class structure is IsJonSkeet. We can use a .NET property to implement this, which is a more modern and expressive way when compared to traditional private/protected fields with a Getter and maybe a Setter.
abstract public class ITTechnician
{
public bool IsJonSkeet { get; protected set; }
protected ITTechnician()
{
this.IsJonSkeet = false;
}
}
public class JonSkeet : ITTechnician
{
public JonSkeet()
{
this.IsJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
}
Now that your itt_type string field has been removed, Whisperity is the same as the base class, so there's no need for a constructor to do any initialisation - it will pick up the IsJonSkeet value of its parent automatically.
+1 for Eric J's class design tips, too. You should use the design of your hierarchy to encapsulate what varies and this makes your calling code much more transparent and the codebase easier to expand on in the future.
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