public class GenoTipController
{
public _Company GenerateCompany(DataModelType modeltype)
{
_Company company = null;
switch (modeltype)
{
case DataModelType.Radyoloji:
break;
case DataModelType.Satis:
break;
case DataModelType.Muayene:
break;
case DataModelType.Company:
company = new Company();
break;
default:
break;
}
return company;
}
public _Muayene GenerateMuayene(DataModelType modeltype)
{
_Muayene muayene = null;
switch (modeltype)
{
case DataModelType.Radyoloji:
break;
case DataModelType.Satis:
break;
case DataModelType.Muayene:
muayene = new Muayene();
break;
case DataModelType.Company:
break;
default:
break;
}
return muayene;
}
public _Radyoloji GenerateRadyoloji(DataModelType modeltype)
{
_Radyoloji radyoloji = null;
switch (modeltype)
{
case DataModelType.Radyoloji:
radyoloji = new Radyoloji();
break;
case DataModelType.Satis:
break;
case DataModelType.Muayene:
break;
case DataModelType.Company:
break;
default:
break;
}
return radyoloji;
}
}
public class CompanyView
{
public static List<Personel> GetPersonel()
{
GenoTipController controller = new GenoTipController();
_Company company = controller.GenerateCompany(DataModelType.Company);
return company.GetPersonel();
}
}
public enum DataModelType
{
Radyoloji,
Satis,
Muayene,
Company
}
}
Refactorings
No refactoring yet !
programmerist
April 16, 2010, April 16, 2010 08:34, permalink
Solution is below!!!!
public class GenoTipController
{
public object CreateByEnum(DataModelType modeltype)
{
string enumText = modeltype.ToString(); // will return for example "Company"
Type classType = Type.GetType(enumText); // the Type for Company class
object t = Activator.CreateInstance(classType); // create an instance of Company class
return t;
}
}
public class CompanyView
{
public static List<Personel> GetPersonel()
{
GenoTipController controller = new GenoTipController();
_Company company = controller.CreateByEnum(DataModelType.Company) as _Company;
return company.GetPersonel();
}
}
public enum DataModelType
{
Radyoloji,
Satis,
Muayene,
Company
}
Ants
April 16, 2010, April 16, 2010 09:36, permalink
@progammerist: I'm puzzled by how your solution works. The DataModelType enum names don't have the leading underscore. How does Type.GetType() know to automatically add in the leading underscore so that Company becomes _Company, Radyoloji becomes _Radyoloji, etc? How are namespaces and nested classes handled in case _Company, _Radyoloji, etc. live in different namespaces and are declared as nested classes?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Other
{
public class Muayene
{
}
}
namespace Test
{
public enum DataModelType
{
Radyoloji,
Muayene,
Satis,
Company,
}
public class _Company
{
}
public class Radyoloji
{
}
public class Outer
{
public class Satis
{
}
}
public interface IController
{
object CreateByEnum(DataModelType modeltype);
}
public class ProgrammeristController : IController
{
public object CreateByEnum(DataModelType modeltype)
{
string enumText = modeltype.ToString();
Type classType = Type.GetType(enumText);
object t = Activator.CreateInstance(classType);
return t;
}
}
public class AntsController : IController
{
static Dictionary<DataModelType, Func<object>> s_creators =
new Dictionary<DataModelType, Func<object>>()
{
{ DataModelType.Radyoloji, () => new Radyoloji() },
{ DataModelType.Company, () => new _Company() },
{ DataModelType.Muayene, () => new Other.Muayene() },
{ DataModelType.Satis, () => new Outer.Satis() },
};
public object CreateByEnum(DataModelType modeltype)
{
return s_creators[modeltype]();
}
}
class Program
{
static void TestController(IController controller)
{
DataModelType [] types = {
DataModelType.Company, // leading underscore
DataModelType.Muayene, // other namespace
DataModelType.Satis, // nested class
DataModelType.Radyoloji, // missing namespace
};
foreach (var value in types)
{
try
{
Console.WriteLine("Creating {0}...", value.ToString());
if (controller.CreateByEnum(value) != null)
Console.WriteLine("Created {0} successfully.", value.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
static void Main(string[] args)
{
TestController(new ProgrammeristController());
TestController(new AntsController());
}
}
}
programmerist
April 16, 2010, April 16, 2010 12:42, permalink
Activator.CreateInstance is very useful. By the way i don't understand you. My codes are so clear! Please add me msn: yusufkaratoprak@yahoo.com. i really want to chat about it?
Ants
April 16, 2010, April 16, 2010 22:14, permalink
@programmerist: Yes, I agree Activator.CreateInstance() is very useful. Unfortunately, you need to pass in the correct type. That means building the correct string to pass to Type.GetType(). If you trace through the call to ProgrammeristController.CreatebyEnum() in the code I posted above, simply doing modelType.ToString() isn't sufficient, even for the case of DataModelType.Radyoloji.
My solution in AntsController above works. The upside is that everything is explicit and fast. The downside is that it'll be maintenance bottleneck.
What would be better is something that takes the results of modelType.ToString() and then recursively searches through all the types found in all the assemblies loaded in the current AppDomain, with appropriate handling of the leading underscore as shown in by the original poster. According to MSDN, Type.GetType() only searches the current calling assembly, and mscorlib.dll.
programmerist
April 17, 2010, April 17, 2010 07:06, permalink
Ants: you said that "My solution in AntsController above works. The upside is that everything is explicit and fast. The downside is that it'll be maintenance bottleneck." . Where is AntsCotroller. Can you give clear solution? My english is not good:(
Ants
April 17, 2010, April 17, 2010 07:59, permalink
AntsController is on lines 54-69 in my first posting above.
Here's another copy of AntsController from above.
public class AntsController : IController
{
static Dictionary<DataModelType, Func<object>> s_creators =
new Dictionary<DataModelType, Func<object>>()
{
{ DataModelType.Radyoloji, () => new Radyoloji() },
{ DataModelType.Company, () => new _Company() },
{ DataModelType.Muayene, () => new Other.Muayene() },
{ DataModelType.Satis, () => new Outer.Satis() },
};
public object CreateByEnum(DataModelType modeltype)
{
return s_creators[modeltype]();
}
}
programmerist
April 17, 2010, April 17, 2010 08:53, permalink
Every thing is very good. But can you give detail "IController"? What does include IController?
Ants
April 17, 2010, April 17, 2010 09:10, permalink
The IController interface was just there so that I could pass both AntsController and ProgrammeristController to my TestController() method and test the common method CreateByEnum(). It is purely for testing. Again, see above.
programmerist
April 17, 2010, April 17, 2010 10:59, permalink
Thanks alot but i can not understand your solution. if i add your codes on my project,error returns. Look this pic: http://i44.tinypic.com/33wa8tc.png
programmerist
April 17, 2010, April 17, 2010 11:33, permalink
Ants; please look my codes . Can you rearrange it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EfTestFactory
{
public abstract class _Company
{
public abstract List<Personel> GetPersonel();
public abstract List<Prim> GetPrim();
public abstract List<Finans> GetFinans();
}
public abstract class _Radyoloji
{
public abstract List<string> GetRadyoloji();
}
public abstract class _Satis
{
public abstract List<string> GetSatis();
}
public abstract class _Muayene
{
public abstract List<string> GetMuayene();
}
public class Company : _Company
{
public override List<Personel> GetPersonel()
{
throw new NotImplementedException();
}
public override List<Prim> GetPrim()
{
throw new NotImplementedException();
}
public override List<Finans> GetFinans()
{
throw new NotImplementedException();
}
}
public class Radyoloji : _Radyoloji
{
public override List<string> GetRadyoloji()
{
throw new NotImplementedException();
}
}
public class Satis : _Satis
{
public override List<string> GetSatis()
{
throw new NotImplementedException();
}
}
public class Muayene : _Muayene
{
public override List<string> GetMuayene()
{
throw new NotImplementedException();
}
}
public class GenoTipController
{
public object CreateByEnum(DataModelType modeltype)
{
string enumText = modeltype.ToString(); // will return for example "Company"
Type classType = Type.GetType(enumText); // the Type for Company class
object t = Activator.CreateInstance(classType); // create an instance of Company class
return t;
}
}
public class AntsController
{
static Dictionary<DataModelType, Func<object>> s_creators =
new Dictionary<DataModelType, Func<object>>()
{
{ DataModelType.Radyoloji, () => new _Radyoloji() },
{ DataModelType.Company, () => new _Company() },
{ DataModelType.Muayene, () => new _Muayene() },
{ DataModelType.Satis, () => new _Satis() },
};
public object CreateByEnum(DataModelType modeltype)
{
return s_creators[modeltype]();
}
}
public class CompanyView
{
public static List<Personel> GetPersonel()
{
GenoTipController controller = new GenoTipController();
_Company company = controller.CreateByEnum(DataModelType.Company) as _Company;
return company.GetPersonel();
}
}
public enum DataModelType
{
Radyoloji,
Satis,
Muayene,
Company
}
}
programmerist
April 17, 2010, April 17, 2010 12:40, permalink
Thanks alot Ants. My brain is too lazy. i see now your adivce and solution.Ant's Solution is best. is it? i like it.
public class AntsController
{
static Dictionary<DataModelType, Func<object>> s_creators =
new Dictionary<DataModelType, Func<object>>()
{
{ DataModelType.Radyoloji, () => new Radyoloji() },
{ DataModelType.Company, () => new Company() },
{ DataModelType.Muayene, () => new Muayene() },
{ DataModelType.Satis, () => new Satis() },
};
public object CreateByEnum(DataModelType modeltype)
{
return s_creators[modeltype]();
}
}
public class CompanyView
{
public static List<Personel> GetPersonel()
{
AntsController controller = new AntsController();
Company company = controller.CreateByEnum(DataModelType.Company) as Company;
return company.GetPersonel();
}
}
public enum DataModelType
{
Radyoloji,
Satis,
Muayene,
Company
}
}
Ants
April 20, 2010, April 20, 2010 01:07, permalink
I hope that you realize with my implementation of AntsController above, you are paying a premium not only for maintenance, but for memory, speed, and code to support the dictionary as well.
It would be cheaper to go with a switch statement instead:
public class AntsController
{
public object CreateByEnum(DataModelType modeltype)
{
switch(modelType)
{
case DataModelType.Radyoloji:
return new Radyoloji();
case DataModelType.Company:
return new Company();
case DataModelType.Muayene:
return new Muayene();
case DataModelType.Satis:
return new Satis();
}
throw new ArgumentOutOfRangeException();
}
}
GenoTipController must produce class according to the enum type. i have 3 class: _Company,_Muayene,_Radyoloji. Also i have CompanyView Class GetPersonel method. if you look GenoTipController my codes need refactoring. Can you understand me? i need a class according to ewnum type must me produce class. For example; case DataModelType.Radyoloji it must return radyoloji= new Radyoloji . Everything must be one switch case?