I am wondering if anyone has any good tutorials(or maybe even a library that is already made and well documented) on making a generic repository.
I am using currently linq to sql but it might change so I don't know if you can make a generic repository that would take little to no changes if I would say switch to entity framework.
Thanks
I think I should also add why I want a generic repository. The reason is in my database I have like corporate tables(users who's subscriptions are paid by someone else) and individual tables(people who find my site through google or whatever and pay for their own subscription)
But I will have 2 very similar tables. For instance I have 2 settings tables one for corporate users and one for the individuals.
Now since they are 2 different tables I need 2 different insert methods as I am inserting it into 2 different tables and at this current time only one field is different(that is the PK).
So now I need all these duplicate methods and I don't want that. Maybe what I have in my database is could be considered as a design flaw(and maybe it is) but one of the reasons behind this was if needed I can break up my database into 2 different databases very easy and I am not going to change my design anytime soon.
Here is my answer to another question of the same type. Hope it helps:
Advantage of creating a generic repository vs. specific repository for each object?
Edit:
It sounds like you want to treat two concrete types as one logical type. To do that, first define the logical type:
public interface ISubscription
{
// ...
}
Then, define the concrete types as part of your data model (interfaces would be implemented in another partial class):
[Table("CorporateSubscription")]
public partial class CorporateSubscription : ISubscription
{
}
[Table("IndividualSubscription")]
public partial class IndividualSubscription : ISubscription
{
}
Next, define the repository which operates on the logical type:
public interface ISubscriptionRepository
{
CorporateSubscription GetCorporate(string key);
IndividualSubscription GetIndividual(int userId);
IEnumerable<ISubscription> ListAll();
IEnumerable<CorporateSubscription> ListCorporate();
IEnumerable<IndividualSubscription> ListIndividual();
void Insert(ISubscription subscription);
}
Finally, implement the interface by using both tables:
public class SubscriptionRepository : ISubscriptionRepository
{
private readonly YourDataContext _dataContext;
public SubscriptionRepository(YourDataContext dataContext)
{
_dataContext = dataContext;
}
#region ISubscriptionRepository
public CorporateSubscription GetCorporate(string key)
{
return _dataContext.CorporateSubscriptions.Where(c => c.Key == key).FirstOrDefault();
}
public IndividualSubscription GetIndividual(int userId)
{
return _dataContext.IndividualSubscriptions.Where(i => i.UserId == userId).FirstOrDefault();
}
public IEnumerable<ISubscription> ListAll()
{
return ListCorporate()
.Cast<ISubscription>()
.Concat(ListIndividual().Cast<ISubscription>());
}
public IEnumerable<CorporateSubscription> ListCorporate()
{
return _dataContext.CorporateSubscriptions;
}
public IEnumerable<IndividualSubscription> ListIndividual()
{
return _dataContext.IndividualSubscriptions;
}
public void Insert(ISubscription subscription)
{
if(subscription is CorporateSubscription)
{
_dataContext.CorporateSubscriptions.InsertOnCommit((CorporateSubscription) subscription);
}
else if(subscription is IndividualSubscription)
{
_dataContext.IndividualSubscriptions.InsertOnCommit((IndividualSubscription) subscription);
}
else
{
// Forgive me, Liskov
throw new ArgumentException(
"Only corporate and individual subscriptions are supported",
"subscription");
}
}
#endregion
}
Here is an example of an insert. Don't get too wrapped up in the presenter class; I just needed a situation in which subscriptions would be created based on a flag:
public class CreateSubscriptionPresenter
{
private readonly ICreateSubscriptionView _view;
private readonly ISubscriptionRepository _subscriptions;
public CreateSubscriptionPresenter(
ICreateSubscriptionView view,
ISubscriptionRepository subscriptions)
{
_view = view;
_subscriptions = subscriptions;
}
public void Submit()
{
ISubscription subscription;
if(_view.IsCorporate)
{
subscription = new CorporateSubscription();
}
else
{
subscription = new IndividualSubscription();
}
subscription.Notes = _view.Notes;
_subscriptions.Insert(subscription);
}
}
Great Linq to Sql resources:
A t4 template that by generates exactly what is created by default, but can be fully customised.
http://l2st4.codeplex.com/
Using Linq to Sql for a multi tier application. It has a GenericObjectDataSource which I have found very handy
http://multitierlinqtosql.codeplex.com
Search all properties of an IQueryable with one single search
http://naspinski.codeplex.com/
Related
I'm new to using SOLID so please excuse my lack of correct terminology, correct me, if needed I am looking to learn :-)
I am in the process of upgrading a library and wanted to use the Open Closed principle, for reason of extensibility without having to modify the provider.
The library intention is to provide a list of modules based on a view type. Based on the type the query and conditions to retrieve the modules is different. Below is an simplied version of the current code:
public class ModuleProvider
{
public List<ITreeNode> GetModules(ViewType viewType)
{
switch (viewType)
{
case ViewType.Classes
//build query here that returns List<TreeNode> for classes
return modules;
case ViewType.Queries
//build query here that returns List<TreeNode> for queries
return modules;
}
}
}
I have read that using the switch statement for examples such as above are bad. I understand why because if I was to add a new ViewType the GetModules will need to change.
I think I have to create an interface that has a GetModules function and then create a class for each i.e a QueryModules and ClassModules class to return then specific list. However, I'm stuck on how will the provider above will need to change to support this? I'm I correct in thinking I will need to use generics for this?
public interface IModuleProvider
{
List<ITreeNode> GetModules();
}
public class QueryModuleProvider : IModuleProvider
{
public List<ITreeNode> GetModules()
{
return new List<ITreeNode>() { new TreeNode() { Type = "Query Module" } };
}
}
public class ClassModuleProvider : IModuleProvider
{
public List<ITreeNode> GetModules()
{
return new List<ITreeNode>() {new TreeNode() { Type = "Class Module"}};
}
}
Am I on the right track? Any help the clever members of stackoverflow can give will be much appreciated.
Thanks
That approach should be fairly obvious that it's not the same - you've changed List<ITreeNode> GetModules(ViewType viewType) to List<ITreeNode> GetModules(). You're now not asking one class for the modules, but you need to decide between two classes - which is exactly the situation you started with. This is a "chicken or the egg" problem.
Instead you should inject in to your a way to dynamically decide how to build your tree nodes.
Here's an approach:
public class ModuleProvider
{
private Dictionary<ViewType, Func<List<ITreeNode>>> _factory;
public ModuleProvider(Dictionary<ViewType, Func<List<ITreeNode>>> factory)
{
_factory = factory;
}
public List<ITreeNode> GetModules(ViewType viewType)
{
return _factory[viewType]();
}
}
When you create the ModuleProvider you're injecting in the dictionary of factories to produce the tree nodes. You can build that dictionary in a myriad of ways without the need to recompile the assembly.
Ignore the fact that DbContext in Entity Framework is unit of work right now.
I wonder how I can simplify creating repositories in class UnitOfWork because now I must add property to that class each time when I create new repository class? I don't want generic repository class.
public class UnitOfWork
{
private SchoolContext _context = new SchoolContext();
private IDepartmentRepository _departmentRepository;
private ICourseRepository _courseRepository;
public IDepartmentRepository DepartmentRepository
{
get
{
if (this._departmentRepository == null)
{
this._departmentRepository = new DepartmentRepository(_context);
}
return _departmentRepository;
}
}
public ICourseRepository CourseRepository
{
get
{
if (this._courseRepository == null)
{
this._courseRepository = new CourseRepository(_context);
}
return _courseRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
}
It's your architecture, so you're the one responsible for providing properties for your repository types. There're several ways of simplifying your code:
There's a shorter way of writing your properties:
ICourseRepository _courseRepository;
public ICourseRepository CourseRepository =>
_courseRepository ?? (_courseRepository = new CourseRepository(_context));
It'll be a little longer with C# 5 or lower (you'll need explicit get accessor). You can also use Lazy<T> type.
Dependency injection. Your getter will look like this:
_someDI.Get<ICourseRepository>(new Parameter(_context));
You'll need to register your types first like this:
_someDI.Register<ICourseRepository, CourseRepository>();
or all types together:
_someDI.RegisterAllImplementingInterface<IBaseRepository>().AsImplementingInterfaces();
It'll also make using single method possible, though types will be less discoverable:
TRep GetRepository<TRep>() where TRep : IBaseRepository =>
_someDI.Get<TRep>(new Parameter(_context));
Code generation using T4. You can read project files to get the list of types and then generate the properties based on that information.
(Maybe) Code generation built into C# 7 when it becomes available. Whether it'll be available and what exactly will be incuded is still TBD.
I am Just creating a 3 Tier WinForm Application with following pattern.
-- MY BASE CLASS : DAL Class
public class Domain
{
public string CommandName = string.Empty;
public List<Object> Parameters = new List<Object>();
public void Save()
{
List<Object> Params = this.SaveEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Delete()
{
List<Object> Params = this.DeleteEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Update()
{
List<Object> Params = this.UpdateEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
protected virtual List<Object> SaveEntity()
{
return null;
}
protected virtual List<Object> UpdateEntity()
{
return null;
}
protected virtual List<Object> DeleteEntity()
{
return null;
}
public int ExecuteNonQuery(string SqlText, params object[] Params)
{
/*
* Code block for executing Sql
*/
return 0;
}
}
My Business Layer Class which is going to inherit DLL Class
-- MY Children CLASS : BLL CLASS
public class Person : Domain
{
public string name
{
get;
set;
}
public string number
{
get;
set;
}
protected override List<object> SaveEntity()
{
this.Parameters.Add(name);
this.Parameters.Add(number);
return this.Parameters;
}
}
-- USE
This is way to use my Base Class
void Main()
{
Person p = new Person();
p.name = "Vijay";
p.number = "23";
p.Save();
}
Questions
Is this the right architecture I am following and Is there any chance to create the base class as Singleton?
Is there any other batter architecture?
Is there any pattern I can follow to extend my functionality?
Kindly suggest.
Lets see. I would try to give my input.
What I see here you are trying to do is ORM. So please change the name of base class from Domain to something else
Is this the right architecture I am following and Is there any chance to create the base class as Singleton?
Why do you need you base class as singleton. You would be inheriting your base class and you would create instances of child classes. Never ever you would be creating a instance of base itself.(99% times :) )
Is there any other batter architecture?
Understand this. To do a certain thing, there could be multiple ways. Its just the matter of fact, which one suits you the most.
Is there any pattern I can follow to extend my functionality?
Always remember the SOLID principles which gives you loose coupling and allow easy extensibility.
SOLID
There are couple of changes that I would suggest. Instead of a base class, start with Interface and then inherit it to make an abstract class.
Also make sure your base class can do all the CRUD functionality. I do not see a retrieval functionality here. How are you planning to do it? Probably you need a repository class that returns all the entity of your application. So when you need person, you would just go on ask the repository to return all the Person.
All said and done, there are lots of ORM tool, that does this kind of functionality and saves developer time. Its better to learn those technologies. For example LINQ - SQL.
Is this the right architecture I am following
There is no architecture which is optimal for any problem without context. That said, there are things that you can do to make your life more difficult. Singleton is not your problem in your implementation.
Is there any other batter architecture?
Probably, yes. Just glimpsing at the code, I see quite a lot of stuff that is going to hurt you in the near and not so near future.
First, a piece of advice: get the basics right, don't run before you can walk. This may be the cause for the downvotes.
Some random issues:
You are talking about 3-Tier architecture, but there are technically no tiers there, not even layers. Person doesn't look like business logic to me: if I understood correctly, it also must supply the string for the commands to execute, so it has to know SQL.
Empty virtual methods should be abstract. If you want to be able to execute arbitrary SQL move this outside the class
As #Anand pointed out, there are no methods to query
CommandName and Parameters are exposed as fields instead of properties
CommandName is not a Name, Domain doesn't look like a fitting name for that class
It looks like an awkward solution to a well-known problem (ORM). You say that you want to be able to execute custom SQL but any decent ORM should be able to let you do that.
Suggested reads: Code Complete for the basic stuff and Architecting Applications for the Enterprise for some clarity on the architectural patterns you could need.
As suggested by Anand, I removed all SQL related functions from my base class and put them all in another class, Sql.
Following that, I made the Sql class into a singleton. And I stored the Sql instance in BaseDAL so it can be accessible in all DAL class.
My code looks something like this
public class BaseDAL
{
// Singleton Instance
protected Sql _dal = Sql.Instance;
public string CommandName = string.Empty;
public List<Object> Parameters = new List<Object>();
public void Save()
{
List<Object> Params = this.SaveEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Delete()
{
List<Object> Params = this.DeleteEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Update()
{
List<Object> Params = this.UpdateEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
protected virtual List<Object> SaveEntity()
{
return null;
}
protected virtual List<Object> UpdateEntity()
{
return null;
}
protected virtual List<Object> DeleteEntity()
{
return null;
}
// Other functions, like DataTable and DataSet querying
}
And the new SQL class is
public class Sql
{
// All other functions are also present in this class for DataTable DataSet and many other
// So this class is more then enough for me.
public int ExecuteNonQuery(string SqlText, params object[] Params)
{
// Code block for executing SQL
return 0;
}
}
CommandName and Parameters are exposed as fields instead of properties. In the original solution, they were properties. Also, I have a method in BaseDAL to query data so to help with implementing the Person class.
I recently started reading Evans' Domain-Driven design book and started a small sample project to get some experience in DDD. At the same time I wanted to learn more about MongoDB and started to replace my SQL EF4 repositories with MongoDB and the latest official C# driver.
Now this question is about MongoDB mapping. I see that it is pretty easy to map simple objects with public getters and setters - no pain there. But I have difficulties mapping domain entities without public setters. As I learnt, the only really clean approach to construct a valid entity is to pass the required parameters into the constructor. Consider the following example:
public class Transport : IEntity<Transport>
{
private readonly TransportID transportID;
private readonly PersonCapacity personCapacity;
public Transport(TransportID transportID,PersonCapacity personCapacity)
{
Validate.NotNull(personCapacity, "personCapacity is required");
Validate.NotNull(transportID, "transportID is required");
this.transportID = transportID;
this.personCapacity = personCapacity;
}
public virtual PersonCapacity PersonCapacity
{
get { return personCapacity; }
}
public virtual TransportID TransportID
{
get { return transportID; }
}
}
public class TransportID:IValueObject<TransportID>
{
private readonly string number;
#region Constr
public TransportID(string number)
{
Validate.NotNull(number);
this.number = number;
}
#endregion
public string IdString
{
get { return number; }
}
}
public class PersonCapacity:IValueObject<PersonCapacity>
{
private readonly int numberOfSeats;
#region Constr
public PersonCapacity(int numberOfSeats)
{
Validate.NotNull(numberOfSeats);
this.numberOfSeats = numberOfSeats;
}
#endregion
public int NumberOfSeats
{
get { return numberOfSeats; }
}
}
Obviously automapping does not work here. Now I can map those three classes by hand via BsonClassMaps and they will be stored just fine. The problem is, when I want to load them from the DB I have to load them as BsonDocuments, and parse them into my domain object. I tried lots of things but ultimately failed to get a clean solution. Do I really have to produce DTOs with public getters/setters for MongoDB and map those over to my domain objects? Maybe someone can give me some advice on this.
It is possible to serialize/deserialize classes where the properties are read-only. If you are trying to keep your domain objects persistance ignorant, you won't want to use BsonAttributes to guide the serialization, and as you pointed out AutoMapping requires read/write properties, so you would have to register the class maps yourself. For example, the class:
public class C {
private ObjectId id;
private int x;
public C(ObjectId id, int x) {
this.id = id;
this.x = x;
}
public ObjectId Id { get { return id; } }
public int X { get { return x; } }
}
Can be mapped using the following initialization code:
BsonClassMap.RegisterClassMap<C>(cm => {
cm.MapIdField("id");
cm.MapField("x");
});
Note that the private fields cannot be readonly. Note also that deserialization bypasses your constructor and directly initializes the private fields (.NET serialization works this way also).
Here's a full sample program that tests this:
http://www.pastie.org/1822994
I'd go with parsing the BSON documents and move the parsing logic to a factory.
First define a factory base class, which contains a builder class. The builder class will act as the DTO, but with additional validation of the values before constructing the domain object.
public class TransportFactory<TSource>
{
public Transport Create(TSource source)
{
return Create(source, new TransportBuilder());
}
protected abstract Transport Create(TSource source, TransportBuilder builder);
protected class TransportBuilder
{
private TransportId transportId;
private PersonCapacity personCapacity;
internal TransportBuilder()
{
}
public TransportBuilder WithTransportId(TransportId value)
{
this.transportId = value;
return this;
}
public TransportBuilder WithPersonCapacity(PersonCapacity value)
{
this.personCapacity = value;
return this;
}
public Transport Build()
{
// TODO: Validate the builder's fields before constructing.
return new Transport(this.transportId, this.personCapacity);
}
}
}
Now, create a factory subclass in your repository. This factory will construct domain objects from the BSON documents.
public class TransportRepository
{
public Transport GetMostPopularTransport()
{
// Query MongoDB for the BSON document.
BsonDocument transportDocument = mongo.Query(...);
return TransportFactory.Instance.Create(transportDocument);
}
private class TransportFactory : TransportFactory<BsonDocument>
{
public static readonly TransportFactory Instance = new TransportFactory();
protected override Transport Create(BsonDocument source, TransportBuilder builder)
{
return builder
.WithTransportId(new TransportId(source.GetString("transportId")))
.WithPersonCapacity(new PersonCapacity(source.GetInt("personCapacity")))
.Build();
}
}
}
The advantages of this approach:
The builder is responsible for building the domain object. This allows you to move some trivial validation out of the domain object, especially if the domain object doesn't expose any public constructors.
The factory is responsible for parsing the source data.
The domain object can focus on business rules. It's not bothered with parsing or trivial validation.
The abstract factory class defines a generic contract, which can be implemented for each type of source data you need. For example, if you need to interface with a web service that returns XML, you just create a new factory subclass:
public class TransportWebServiceWrapper
{
private class TransportFactory : TransportFactory<XDocument>
{
protected override Transport Create(XDocument source, TransportBuilder builder)
{
// Construct domain object from XML.
}
}
}
The parsing logic of the source data is close to where the data originates, i.e. the parsing of BSON documents is in the repository, the parsing of XML is in the web service wrapper. This keeps related logic grouped together.
Some disadvantages:
I haven't tried this approach in large and complex projects yet, only in small-scale projects. There may be some difficulties in some scenarios I haven't encountered yet.
It's quite some code for something seemingly simple. Especially the builders can grow quite large. You can reduce the amount of code in the builders by converting all the WithXxx() methods to simple properties.
A better approach to handling this now is using MapCreator (which was possibly added after most of these answers were written).
e.g. I have a class called Time with three readonly properties: Hour, Minute and Second. Here's how I get it to store those three values in the database and to construct new Time objects during deserialization.
BsonClassMap.RegisterClassMap<Time>(cm =>
{
cm.AutoMap();
cm.MapCreator(p => new Time(p.Hour, p.Minute, p.Second));
cm.MapProperty(p => p.Hour);
cm.MapProperty(p => p.Minute);
cm.MapProperty(p => p.Second);
}
Niels has an interesting solution but I propose a much different approach:
Simplify your data model.
I say this because you are trying to convert RDBMS style entities to MongoDB and it doesnt map over very well, as you have found.
One of the most important things to think about when using any NoSQL solution is your data model. You need to free your mind of much of what you know about SQL and relationships and think more about embedded documents.
And remember, MongoDB is not the right answer for every problem so try not to force it to be. The examples you are following may work great with standard SQL servers but dont kill yourself trying to figure out how to make them work with MongoDB - they probably dont. Instead, I think a good excercise would be trying to figure out the correct way to model the example data with MongoDB.
Consider NoRM, an open-source ORM for MongoDB in C#.
Here are some links:
http://www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx
http://lukencode.com/2010/07/09/getting-started-with-mongodb-and-norm/
https://github.com/atheken/NoRM (download)
I'm struggling with a small issue with regard to how I go about refactoring this to a decent pattern.
public class DocumentLibrary
{
private IFileSystem fileSystem;
private IDocumentLibraryUser user;
public DocumentLibrary(IDocumentLibraryUser user) : this(user, FileSystemFrom(user)) { }
public DocumentLibrary(IDocumentLibraryUser user, IFileSystem fileSystem)
{
this.user = user;
this.fileSystem = fileSystem;
}
public void Create(IWorkerDocument document)
{
document.SaveTo(fileSystem);
}
public IWorkerDocument AttemptContractRetrieval()
{
return new Contract(fileSystem, user);
}
public IWorkerDocument AttemptAssignmentRetrieval()
{
return new Assignment(fileSystem, user);
}
private static IFileSystem FileSystemFrom(IDocumentLibraryUser user)
{
var userLibraryDirectory = new DirectoryInfo("/DocLib/" + EnvironmentName() + "/" + user.Id);
return new FileSystem(userLibraryDirectory);
}
private static string EnvironmentName()
{
using (var edmxContext = new Entities())
{
return (from setting in edmxContext.EnvironmentSettings
where setting.Name == "EnvironmentName"
select setting.Value).First();
}
}
}
I have two types of worker documents, but I can't seem to easily refactor the two methods above (AttemptContractRetrieval and AttemptAssignmentRetrieval) to a decent form.
Any help would be much appreciated.
Regards,
Jim.
Personnally, I would consider either a factory pattern using factory methods or a builder pattern.
Good use of the factory pattern can be seen in the Enterprise Library solution e.g:
Database.CreateDatabase();
I would say this would be the most straight forward to integrate.
If you chose the Builder pattern, with a requirement to create more complex objects, then you can separate out the creation of complex objects into a series of build commands e.g:
vehicleBuilder.BuildFrame();
vehicleBuilder.BuildEngine();
vehicleBuilder.BuildWheels();
vehicleBuilder.BuildDoors();
Then within these methods, given your chosen implementation, you can add your complexity but make the method calls and construction quite straight forward.
If you haven't come across it, http://www.dofactory.com is a good place to go.
I can see two aspects to this:
What do I need to do to add a new IWorkerDocument class? Adding new methods seems heavyweight.
What code does the caller need in order to create an IWorkerDocument? Right now the responsibility for calling the correct method lies with the caller, hence it's quite likely that the caller also needs to change each time there is a new IWorkerDocument implementor.
The extent of possible refactoring very much depends upon the answer to 2. Sometimes the caller just has to know what they're making, and in which case the code you have is pretty much all you can do. In other cases you have some "WorkerDefinition" stuff, perhaps in the form of a set of Properties, or a name that can be looked up in a registry. In which case the caller wants an api of the form
makeMeAWorker(WorkerDefinition def)
on a Factory. Now the caller has no idea what he's asking for, delegates the whole thing to the factory. So the client's world need not change as you add new Worker types.
The Factory can be made extensible by some form of registration scheme or dynamic configuration scheme. We can inject new types into the factory by many different mechanisms.
I think it depends on what other responsibilities the class has that contains those methods. Design patterns are structural constructs. Here we infer that there is a class
class Retriever
{
...
public IWorkerDocument AttemptContractRetrieval()
{
}
public IWorkerDocument AttemptAssignmentRetrieval()
{
}
}
The client code is already deciding whether to call AttemptContractRetrieval(), or AttemptAssignmentRetrieval, so maybe polymorphism is in order.
class ContractRetriever
{
public IWorkerDocument AttemptRetrieval()
{
}
}
class AssignmentRetriever
{
public IWorkerDocument AttemptRetrieval()
{
}
}
You can make an abstract Retriever class and have these as descendents of that. This will force the derived classes to have an AttemptRetrieval() method.
If you execute similar actions on the retrieved documents, you may consider having Contract and Assignment classes instead of ContractRetriever and AssignmentRetriever. Then you can put common actions in their parent.
In short, a lot of the answer here lies in the unstated context of the problem.
For interested people, I have gone for a factory method.
public IWorkerDocument AttemptRetrieval<T>() where T : IWorkerDocument
{
return WorkerDocument.Create<T>(fileSystem, user);
}
calls
public static IWorkerDocument Create<T>(IFileSystem fileSystem, IDocumentLibraryUser user) where T : IWorkerDocument
{
var documentType = typeof(T);
if (documentType == typeof(Contract))
return new Contract(fileSystem, user);
if (documentType == typeof(Assignment))
return new Assignment(fileSystem, user);
throw new Exception("Invalid Document Type");
}
It's a little messy, so does anyone have any suggestions to clean the actual factory method up?
what about this:
public IWorkerDocument AttemptRetrieval<T>() where T:new, IWorkerDocument
{
return new T {FileSystem=fileSystem,User=user}
}
Out of the top of my head, so may contain a blatant error ;-)
Are you looking for the Abstract Factory pattern? The declared intent in 'Design Patterns' is "Provide an interface for creating families of related or dependent objects without specifying their concrete classes."
http://en.wikipedia.org/wiki/Abstract_factory