C# Design Pattern - Best Way to Design For Many Datasources [duplicate] - c#

This question already has answers here:
How to avoid Dependency Injection constructor madness?
(10 answers)
Closed 7 years ago.
I currently have an ASP.Net MVC 5 app that uses 3 external datasources (calls are made to external APIs, responses are deserialized, and mapped to business POCOs).
The app currently uses SimpleInjector to inject concrete repositories for each datasource into a business logic layer for consumption.
The problem is, as more datasources are added (potentially 20-30), the constructor will be huge and injecting all these repositories seems cumbersome.
Is there a better pattern/approach to consuming all the datasources rather than using different repositories?
Would a facade or some other pattern be more appropriate?
Very generic examples:
public class MyObject(){
public IEnumerable<Cat> Cats { get; set; }
public IEnumerable<Dog> Dogs { get; set; }
public IEnumerable<Fish> Fish { get; set; }
}
public class BusinessLogic{
private readonly ISourceARepository _sourceA;
private readonly ISourceBRepository _sourceB;
private readonly ISourceCRepository _sourceC;
public BusinessLogic(ISourceARepository sourceA, ISourceBRepository sourceB, ISourceCRepository sourceC){
_sourceA = sourceA;
_sourceB = sourceB;
_sourceC = sourceC;
}
private Dog MapSourceARecordToDog(SourceARecord record){
var result = new Dog();
if(record != null){
result.Name = record.NameField;
result.Age = record.Age;
}
return result;
}
private Cat MapSourceBRecordToCat(SourceBRecord record){
var result = new Cat();
if(record != null){
result.Name = record.NameField;
result.Weight = record.WeightField;
}
return result;
}
private Fish MapSourceCRecordToFish(SourceCRecord record){
var result = new Fish();
if(record != null){
result.ID = record.IDField;
result.Name = record.NameField;
}
return result;
}
public MyObject GetResults(){
var result = new MyObject();
result.Dogs = _sourceA.GetAll().Select(MapSourceARecordToDog).ToList();
result.Cats = _sourceB.GetAll().Select(MapSourceBRecordToCat).ToList();
result.Fish = _sourceC.GetAll().Select(MapSourceCRecordToFish).ToList();
return result;
}
}
public class SourceARespository : ISourceARepository{
public IEnumerable<SourceAResult> GetAll(){
return new List<SourceAResult>();
}
}
public class SourceBRespository : ISourceBRepository{
public IEnumerable<SourceBResult> GetAll(){
return new List<SourceBResult>();
}
}
public class SourceCRespository : ISourceCRepository{
public IEnumerable<SourceCResult> GetAll(){
return new List<SourceCResult>();
}
}
Update:
This is not a duplicate of the constructor madness question, because in this scenario, a class needs many different datasources, but still has single responsibility. Hence, it warrants its own explanation and answer.

You should only be injecting one repository per entity into a consumer that depends on it. You may also choose to adapt the repository with a business class intermediary.
UPDATE:
Based on the information provided in the question and the problem statement, here is one possible solution. Define your core infrastructure like this:
public abstract class Entity<TEntity, TDomainObject, TIRepository>
where TEntity : Entity<TEntity, TDomainObject, TIRepository>
where TDomainObject : Entity<TEntity, TDomainObject, TIRepository>.BaseDomainObject, new()
where TIRepository : Entity<TEntity, TDomainObject, TIRepository>.IBaseRepository
{
public class BaseDomainObject {}
public interface IBaseRepository
{
IEnumerable<TDomainObject> GetAll();
IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper);
}
public class BaseRepository : IBaseRepository
{
public IEnumerable<TDomainObject> GetAll()
{
return new List<TDomainObject>();
}
public IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper)
{
return this.GetAll().Select(mapper);
}
}
}
Define your source entities like this:
public class SourceA : Entity<SourceA, SourceA.DomainObject, SourceA.IRepository>
{
public class DomainObject : BaseDomainObject
{
public string Name;
public int Age;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
public class SourceB : Entity<SourceB, SourceB.DomainObject, SourceB.IRepository>
{
public class DomainObject : BaseDomainObject
{
public string Name;
public decimal Weight;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
public class SourceC : Entity<SourceC, SourceC.DomainObject, SourceC.IRepository>
{
public class DomainObject : BaseDomainObject
{
public Guid Id;
public string Name;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
Then define an ISourceRepositoryContext interface like this and add each source repository interface here:
public interface ISourceRepositoryContext
{
SourceA.IRepository SourceARepository { get; }
SourceB.IRepository SourceBRepository { get; }
SourceC.IRepository SourceCRepository { get; }
}
Then define a default implementation for the interface:
public class DefaultSourceRepositoryContext : ISourceRepositoryContext
{
public SourceA.IRepository SourceARepository => new SourceA.Repository();
public SourceB.IRepository SourceBRepository => new SourceB.Repository();
public SourceC.IRepository SourceCRepository => new SourceC.Repository();
}
Define your result transport objects:
public class Dog
{
public string Name;
public int Age;
}
public class Cat
{
public string Name;
public decimal Weight;
}
public class Fish
{
public Guid Id;
public string Name;
}
public class MyObject
{
public IEnumerable<Cat> Cats { get; set; }
public IEnumerable<Dog> Dogs { get; set; }
public IEnumerable<Fish> Fish { get; set; }
}
Then consume the ISourceRepositoryContext in your BusinessLogic class:
public class BusinessLogic
{
protected ISourceRepositoryContext repositories;
public BusinessLogic(ISourceRepositoryContext repositories)
{
this.repositories = repositories;
}
public MyObject GetResults(string param1)
{
return new MyObject()
{
Dogs = this.repositories.SourceARepository.GetAllMapped
(domainObject=>new Dog
{
Age = domainObject.Age,
Name = domainObject.Name
}),
Cats = this.repositories.SourceBRepository.GetAllMapped
(domainObject=>new Cat
{
Name = domainObject.Name,
Weight = domainObject.Weight
}),
Fish = this.repositories.SourceCRepository.GetAllMapped
(domainObject=>new Fish
{
Id = domainObject.Id,
Name = domainObject.Name
}),
};
}
}
I've confirmed that the above compiles under C# 6.0.
I would recommend changing IRepository to IBusiness in Entity and split out the data access concerns from into an IDataAccess interface that only the IBusiness implementors receive via their constructors. And then change the ISourceRepositoryContext to ISourceEntities and change the IRepository properties in that interface to IBusiness properties instead.
The BusinessLogic class is the part that really concerns me. Are you sure this one class won't be taking on too many concerns? Is this supposed to be a UoW class?
For a more complete solution based on similar techniques, check out my answer to this other question: .NET Managing Layers Relationships

Related

c# circular generic type parameters

I have 2 generic classes: a ManagerBase class and a ChildBase class.
They're both abstract and are intended to be made concrete.
ManagerBase has a list of ChildBase, which is why I want to make it generic, so a CatalogManager : ManagerBase would have a list of Catalogs. Also, each Catalog would have reference to its' Manager - CatalogManager.
public class ManagerBase<T1> : ChildBase<???>
{
public ManagerBase()
{
ChildObjects = new List<T1>();
}
public List<T1> ChildObjects { get; set; }
}
public class ChildBase<T1> : ManagerBase<???>
{
public ChildBase(T1 parentMgr)
{
ParentMgr = parentMgr;
ParentMgr.ChildObjects.Add(this);
}
public T1 ParentMgr { get; set; }
}
How can I resolve this object model?
Thanks.
You have to define the base classes using the "curiously recursive" pattern:
public class ManagerBase<M, T1>
where M : ManagerBase<M, T1>
where T1 : ChildBase<M, T1>
{
public ManagerBase()
{
ChildObjects = new List<T1>();
}
public List<T1> ChildObjects { get; set; }
}
public class ChildBase<T1, C>
where T1 : ManagerBase<T1, C>
where C : ChildBase<T1, C>
{
public ChildBase(T1 parentMgr)
{
ParentMgr = parentMgr;
ParentMgr.ChildObjects.Add((C)(object)this);
}
public T1 ParentMgr { get; set; }
}
Please note I've stuck with your usage of T1, but I think that's a bit confusing. I would have preferred to have used M and C for each.
The major downside with this is that you have to use the nasty double cast of (C)(object)this to make this work. C# doesn't allow full type safety on this pattern. A nefarious developer can create child classes that can break the pattern.
Then the concrete classes can be this:
public class CatalogManager : ManagerBase<CatalogManager, Catalog>
{
}
public class Catalog : ChildBase<CatalogManager, Catalog>
{
public Catalog(CatalogManager parentMgr) : base(parentMgr)
{
}
}

Complex LINQ query to build two lists, cast each value in each list, and combine lists?

I have three interfaces in my application
public interface FBBase { }
public interface IFoo : FBBase { }
public interface IBar : FBBase { }
I also have a class that holds a List of both IFoo and IBar
public class FBUser
{
public List<IFoo> foos { get; set; }
public List<IBar> bars { get; set; }
}
And some classes that implement these interfaces
public class Fee : IFoo { }
public class Baz : IBar { }
public class PhiBat : IFoo, IBar { }
In another class I do some work with FBUser objects. I would like to collect a List<IFBBase> that contains each unique reference in FBUser.foos and FBUser.bars. Furthermore I would like to also disclude certain Type from the List<IFBBase>.
Is there a cleaner way to do it than this? Is this the correct way to do it?
public class FBUserWorker
{
List<Type> discludeTypes { get; set; } = new List<Type>();
public FBUserWorker()
{
discludeTypes.Add(typeof(PhiBat));
}
public void DoWork(FBUser userObj)
{
var fbBaseList = userObj.foos.Where(x => !discludeTypes.Contains(x.GetType())).Cast<IFBBase>().ToList();
fbBaseList.AddRange(userObj.bars.Where(x => !discludeTypes.Contains(x.GetType())).Cast<IFBBase>().ToList());
fbBaseList = fbBaseList.Distinct().ToList();
}
}
Use Concat to merge the lists (converted to IEnumerable<IFBase>) and then run the Where and Distinct logic:
result = userObj.foos.Cast<IFBBase>()
.Concat(userObj.bars.Cast<IFBase>())
.Where(x => !discludeTypes.Contains(x.GetType()))
.Distinct()
.ToList();

Constructor injection - binding two separate configuration dependencies into a repository class

What is the best practice, following DI, to create two separate repository classes...e.g.
public class FirstDbRepo : Repository
public class SecondDbRepo : Repository
That essentially implement the Repository class shown below
namespace MyApp.Persistence
{
public class Repository<T> : IRepository<T> where T : EntityBase
{
public IConfig Config { get; set; }
private Database Database
{
get
{
// Use Config to get connection
};
set;
}
public Repository(IConfig config)
{
Config = config;
}
public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
{
// Use database to get items
}
public T CreateItem(T item)
{
// Use database to create item
}
}
}
But to inject different config values/instances...
public interface IConfig
{
string DatabaseName{ get; }
string DatabaseEndpoint{ get; }
string DatabaseAuthKey{ get; }
}
The first thing I thought of was to create marker interfaces, but wanted to know if this smells...is there a more correct way to do this using DI?
public interface IFirstDbRepo { }
public class FirstDbRepo<T> : Repository<T> where T: EntityBase
{
public FirstDbRepo(FirstConfig config)
: base(config)
{ }
}
public class FirstConfig : IConfig
{
public string DatabaseName{ get { return "MyName" }; } // From web.config
}
And then use a ninject binding for each repo...the consumer could use as follows
public class Consumer() {
private readonly IFirstDbRepo _firstRepo;
public Consumer(IFirstDbRepo firstRepo) {
_firstRepo = firstRepo;
}
}
Bind<IConfig>().To<MyConfigOne>().WhenInjectedInto(typeof(FirstDbRepo));
Bind<IConfig>().To<MyConfigTwo>().WhenInjectedInto(typeof(SecondDbRepo ));
Contextual binding

Should Repositories's services depend on each other?

Assume I have 2 entities Foo and Bar as follows:
public class Foo
{
public int FooID {get;set;}
public string FooName {get;set;}
}
public class Bar
{
public int BarID {get;set;}
public string BarName {get;set;}
public int FooID {get;set;}
}
For each entity will have its repository:
public class FooRepository
{
public IEnumerable<Foo> getFoo()
{
//do something
}
}
public class BarRepository
{
public IEnumerable<Bar> getBar()
{
//do something
}
public IEnumerable<Bar> getBar(int FooID)
{
//get bar base on foo id
}
}
Each of those repositories will have an associated service:
public class FooService
{
//depend on Foo repository
}
public class BarService
{
//depend on Bar repository
}
Now I want to make a function to see if a Foo is in used in Bar. I thought of 2 methods to implement this function:
Method 1:
public class BarService
{
private BarRepository repository = new BarRepository();
public bool isFooExisted(int FooID)
{
var bars = this.repository.getBar(FooID);
return bars.Count > 0;
}
}
Somehow, this is look like it is violating Single Responsible Principle since BarService is used to check for a Foo. So I came up with method 2:
Method 2:
public class BarService
{
private BarRepository repository = new BarRepository();
public IEnumerable<Bar> getBar(int FooID)
{
return this.repository.getBar(FooID);
}
}
public class FooService
{
private BarService service = new BarService();
public bool isFooExisted(int FooID)
{
var bars = service.getBar(FooID);
return bars.Count > 0;
}
}
I wonder is it a good idea for services depend on each other like this. Please suggest me which one of those method above is good to follow or any other method will help
I personally would avoid services using other services because sooner or later you'll get a circular reference. Having the services not depend on each other also makes for looser coupling and ease of testability. So i would go for method 1.
The problem with this approach comes when you want to reuse functionality between services. In your case you can just defer calls to the respective repository, but in more complex cases you may need to add a domain object that contain common business logic that can be re-used in the different services. For example, if you had to have a complex isFooExisted method in both services, you might do something like this (note that I have changed your code to use dependency injection to make your code more testable):
public class BarService
{
private FooEntity fooEntity;
public BarService(IFooRepository repository)
{
this.fooEntity = new FooEntity(repository);
}
public IEnumerable<Foo> getFoo(int FooID)
{
return fooEntity.getFoo(FooID);
}
}
public class FooService
{
private FooEntity fooEntity;
public FooService(IFooRepository repository)
{
this.fooEntity = new FooEntity(repository);
}
public IEnumerable<Foo> getFoo(int FooID)
{
return fooEntity.getFoo(FooID);
}
}
public class FooEntity
{
private IFooRepository repository;
public FooEntity(IFooRepository repository)
{
this.repository = repository;
}
public bool isFooExisted(int FooID)
{
/** Complex business logix **/
}
}
And for the simple case I'd just use the same repository directly and not have the domain object:
public class BarService
{
private IFooRepository repository;
public BarService(IFooRepository repository)
{
this.repository = repository;
}
...
}
public class FooService
{
private IFooRepository repository;
public FooService(IFooRepository repository)
{
this.repository = repository;
}
...
}
Hope this helps.

Register abstract managed classes with generic managing class and preserve one-to-many relationship

I have a couple abstract classes, and would like to make sure that the "Manager" is always registered with the "Managed" class such that they retain a two-way knowledge of the one-to-many relationship. That is, the Manager knows all of the Managed classes it has, and the Managed class knows who its Manager is (if it is registered with one). Further, I'd like the managed class to be able to call the specialization of its concrete manager without having to do a special cast. Is that possible?
I'd like something like this, but run into compilation issues:
class Program
{
static void Main(string[] args)
{
ConcreteManager manager = new ConcreteManager();
ConcreteManaged managed = new ConcreteManaged() { Name = "Test" };
manager.Add(managed);
managed.Process();
}
}
public abstract class BaseManager<ManagedType>
where ManagedType : BaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = this; // Cannot implicitly convert type 'BaseManager<ManagedType>' to 'BaseManager<BaseManaged>' (I've tried casting to no avail)
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<BaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh Called"); }
}
public abstract class BaseManaged
{
public string Name { get; set; }
public BaseManager<BaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
Manager.Refresh();
}
}
If I change the non Program classes around a bit, as follows, I can get it to compile, but there are runtime errors (Unable to cast object of type 'TestAbstractGenerics.ConcreteManager' to type 'TestAbstractGenerics.IBaseManager`1[TestAbstractGenerics.IBaseManaged]'.):
public interface IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
void Add(ManagedType service);
}
public abstract class BaseManager<ManagedType> : IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = (IBaseManager<IBaseManaged>)this;
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<BaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public interface IBaseManaged
{
string Name { get; set; }
IBaseManager<IBaseManaged> Manager { get; set; }
}
public abstract class BaseManaged : IBaseManaged
{
public string Name { get; set; }
public IBaseManager<IBaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
((ConcreteManager)Manager).Refresh();
}
}
If I change the IBaseManager<IBaseManaged> to dynamic I can remove the cast from Process() and everything works as expected, but dynamic doesn't work with intellisense, and I would like to be able to enforce the type checking (so an implementer can't accidentally set Manager to a string, for example). So what's the best practice here? Is there a good pattern to follow that allows me to preserve the one-to-many relationship?
And yes, in the above I'd have to add some logic to make sure that when BaseManaged.Manager is set that it unregisters from its current Manager, if any. I avoided that here for sake of simplicity.
Edit: this works, but still requires casting to the ConcreteManager prior to calling its non-interface methods:
class Program
{
static void Main(string[] args)
{
var manager = new ConcreteManager();
var managed = new ConcreteManaged() { Name = "Test"};
manager.Add(managed);
managed.Process();
}
}
public interface IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
void Add(ManagedType managed);
}
public abstract class BaseManager<ManagedType> : IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = (IBaseManager<IBaseManaged>)this;
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<IBaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public interface IBaseManaged
{
string Name { get; set; }
IBaseManager<IBaseManaged> Manager { get; set; }
}
public abstract class BaseManaged : IBaseManaged
{
public string Name { get; set; }
public IBaseManager<IBaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
((ConcreteManager)Manager).Refresh();
}
}
I'm pretty sure the kind of cyclic relationship you want is not possible to implement perfectly type safe and without casts, because the compiler would end up getting into infinite cycles if you wanted IBaseManaged also to be generic (ie, IBaseManaged<T> where T : IBaseManager<?>), is clearly not possible to specify the constraint you need in place of ?.
You can however, create a third interface/class which can fully express this kind of circular constraint, which might provide an alternative solution.
interface IManagerAdapter<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager>
IMO, if your ConcreteManaged class is going to know directly about ConcreteManager by virtue of the type cast anyway, these classes don't really provide much more than a pattern to follow for concrete types, the abstraction is kind of broken. If you need this tight coupling between the specific concrete manager and managed types anyway, I would probably make it explicity by adding the specific type in place of Managed in each class, and do away with the BaseManaged class, which doesn't help very much other than providing the Name, which is simple enough to re-implement in concrete instances.
public interface IBaseManaged<T> {
string Name { get; set; }
T Manager { get; set; }
}
public class ConcreteManaged : IBaseManaged<ConcreteManager> {
public string Name { get; set; }
public ConcreteManager Manager { get; set; }
public void Process ()
{
Manager.Refresh ();
}
}
For anything in the base types which might be more complex to implement than Name, I would opt for a Mixin like approach, where you implement that additional functionality in a separate class, and just provide a property in the interface to retreive the Mixin. For example, if all the Manager classes need to account for registering all of the Managed (as with your Add()), you obviously don't want to duplicate that functionality in each Manager - but you could simplify the approach by implementing some ManagedRegister<T> type, say (can be whatever you like), and giving the IBaseManager type a Registered field to retreive an instance.
public interface IBaseManager<T> {
ManagedRegister<T> Registered { get; set; }
}
public class ConcreteManager : IBaseManager<ConcreteManaged> {
public ManagedRegister<ConcreteManaged> Registered { get; set; }
public void Refresh () { Console.WriteLine("Refresh() called"); }
}
You still get a strongly typed Managed instances from the Register inside the Manager here.
The change from your calling code is that instead of manager.Add(managed), it becomes manager.Registered.Add(managed), and you also need to create an instance of ManagedRegister<ConcreteManaged> to pass to the ConcreteManager.. Perhaps a bit messy, and I would suggest abstracting that away into a factory, which will prevent simple mistakes like forgetting to add managed instances to the manager. We can use that circular constraint from above to implement it in a type safe way. (And if it's possible to assume every Managed/Manager has a parameterless constructor, a single implementation will work by using new() constraints. Otherwise you'll want an abstract factory and implement for each concrete type).
interface IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager>
{
TManager Manager { get; }
TManaged Create (string name);
}
public abstract class ManagerFactory<TManager, TManaged>
: IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>, new()
where TManaged : IBaseManaged<TManager>, new()
{
TManager manager = new TManager ();
public ManagerFactory () {
manager.Registered = new ManagedRegister<TManaged> ();
}
public TManager Manager { get { return manager; } }
public TManaged Create (string name)
{
TManaged result = new TManaged ();
result.Name = name;
manager.Registered.Add (result.Name, result);
result.Manager = manager;
return result;
}
}
public class ConcreteFactory
: ManagedFactory<ConcreteManager, ConcreteManaged> { }
Back to Main, the usage is slightly simplified here.
ConcreteFactory f = new ConcreteFactory ();
ConcreteManaged managed = f.CreateManaged ("Test");
managed.Process ();
EDIT:
Here's abstracting all of the common functionality into so called "Base classes". The key difference here is that the Base classes composed into the concrete class rather than inherited, by means of the Base property, which acts very much like the base. prefix you'd use to call base members usually.
public class BaseManager<T> {
public Dictionary<string, T> Registered { get; set; }
}
public interface IBaseManager<T> {
BaseManager<T> Base { get; set; }
}
public class ConcreteManager
: IBaseManager<ConcreteManaged> {
public BaseManager<ConcreteManaged> Base { get; set; }
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public class BaseManaged<T> {
public string Name { get; set; }
public T Manager { get; set; }
}
public interface IBaseManaged<T> {
BaseManaged<T> Base { get; set; }
}
public class ConcreteManaged
: IBaseManaged<ConcreteManager> {
public BaseManaged<ConcreteManager> Base { get; set; }
internal ConcreteManaged () { }
public void Process () {
Base.Manager.Refresh ();
}
}
interface IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager> {
TManager Manager { get; }
TManaged Create (string name);
}
public abstract class BaseManagerFactory<TManager, TManaged>
: IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>, new()
where TManaged : IBaseManaged<TManager>, new() {
TManager manager = new TManager();
public BaseManagerFactory() {
manager.Base = new BaseManager<TManaged>();
manager.Base.Registered = new Dictionary<string, TManaged>();
}
public TManager Manager { get { return manager; } }
public TManaged Create (string name) {
TManaged result = new TManaged();
result.Base = new BaseManaged<TManager>();
result.Base.Name = name;
manager.Base.Registered.Add (name, result);
result.Base.Manager = manager;
return result;
}
}

Categories