Abstract Factory – Provide the classes or interface classes for creating several classes and objects in the superclass. It allows the superclass to alter the object type or other that will be made.
From Design Pattern – Creational Patterns
Structure
Applicability
Using the abstract factory that the programs work with other related objects, the developers don’t want the source code to depend on the specific class. Maybe the developers know future extensibility or unknown preparatory that is why the developers use the abstract factory.
The abstract factory provides the interface classes or the abstract classes for creating objects from each subclass. Everyone class must have the responsibility only for a single thing. When the subclasses with multiple object types, maybe the programs must import the different factory methods into a stand-alone factory class.
Pros and Cons
Pros
Cons
How to Implement
#1 Basic Sample
public interface IAbstractFactory<T> where T : class
{
IAbstractFactoryRepositoryA<T> CreateA(T entity);
IAbstractFactoryRepositoryB<T> CreateB(T entity);
}
class Repository<T> : IAbstractFactory<T> where T : class
{
public IAbstractFactoryRepositoryA<T> CreateA(T entity)
{
return new AbstractFactoryRepositoryA<T>();
}
public IAbstractFactoryRepositoryB<T> CreateB(T entity)
{
return new AbstractFactoryRepositoryB<T>();
}
}
public interface IAbstractFactoryRepositoryA<T> where T:class
{
bool Create(T entity);
}
public interface IAbstractFactoryRepositoryB<T> where T : class
{
bool Create(T entity);
}
class AbstractFactoryRepositoryA<T> : IAbstractFactoryRepositoryA<T> where T : class
{
public bool Create(T entity) => true;
}
class AbstractFactoryRepositoryB<T> : IAbstractFactoryRepositoryB<T> where T : class
{
public bool Create(T entity) => true;
} #2 Web Application Project
Step1 Create two interface classes and the generic repository classes. One interface class file name sets “IAbstractFactoryA.” Another interface class file name sets “IAbstractFactoryB.” One generic repository class file name sets “AbstractFactoryA_Repository.” Another interface class file name sets “AbstractFactoryB_Repository.”
Step 2 Create CRUD in each repository and the “Get” function about the database connection to check the database connection status. The “Get” function helps the developer to double-check the dependency injection issue.
public class AbstractFactoryA_Repository<T> : IAbstractFactoryA<T> where T : class
{
private readonly DemoDbContext dbContext;
public AbstractFactoryA_Repository(DemoDbContext _dbContext)
{
this.dbContext = _dbContext;
}
public AbstractFactoryA_Repository()
{ }
public Task<bool> Get()
{
if (dbContext != null)
{
var o = dbContext.Set<T>().ToList();
return Task.FromResult(true);
}
else
return Task.FromResult(false);
}
public Task<IEnumerable<T>> GetAll()
{
try
{
var obj = dbContext.Set<T>().ToList() as IEnumerable<T>;
return Task.FromResult(obj);
}
catch (Exception e)
{
Debug.WriteLine("Commit Exception Type: {0}", e.GetType());
Debug.WriteLine("Message: {0}", e.Message);
return null;
}
}
public Task<T> GetByID(int? id)
{
try {
var obj = dbContext.Set<T>().Find(id.Value) as T;
return Task.FromResult(obj);
}
catch (Exception e)
{
Debug.WriteLine("Commit Exception Type: {0}", e.GetType());
Debug.WriteLine("Message: {0}", e.Message);
return null;
}
}
public Task Create(T entity)
{
try
{
dbContext.Set<T>().Add(entity);
dbContext.SaveChanges();
return Task.FromResult(true);
}
catch (Exception e)
{
Debug.WriteLine("Commit Exception Type: {0}", e.GetType());
Debug.WriteLine("Message: {0}", e.Message);
return Task.FromResult(false);
}
}
public Task Update(T entity)
{
try
{
dbContext.Entry(entity).State = EntityState.Modified;
dbContext.SaveChanges();
return Task.FromResult(true);
}
catch (Exception e)
{
Debug.WriteLine("Commit Exception Type: {0}", e.GetType());
Debug.WriteLine("Message: {0}", e.Message);
return Task.FromResult(false);
}
}
public Task Delete(T entity)
{
try
{
dbContext.Entry(entity).State = EntityState.Deleted;
dbContext.SaveChanges();
return Task.FromResult(true);
}
catch (Exception e)
{
Debug.WriteLine("Commit Exception Type: {0}", e.GetType());
Debug.WriteLine("Message: {0}", e.Message);
return Task.FromResult(false);
}
}
}
Step 3 Create an interface class that describes all of the interface-generic repositories. This interface class file name sets “IAbstractFactory.”
public interface IAbstractFactory<T> where T : class
{
IAbstractFactoryA<T> CreateA();
IAbstractFactoryB<T> CreateB();
} Step 4 Create a generic repository for the “IAbstractFactory.” This repository class file name sets “AbstractFactoryRepo.”
Step 6 Statement two interface functions and do the dependency injection about IAbstractFactoryA and IAbstractFactoryB.
public class AbstractFactoryRepo<T> : IAbstractFactory<T> where T : class
{
private readonly IAbstractFactoryA<T> RepoA;
private readonly IAbstractFactoryB<T> RepoB;
public AbstractFactoryRepo(
IAbstractFactoryA<T> _RepoA,
IAbstractFactoryB<T> _RepoB)
{
this.RepoA = _RepoA;
this.RepoB = _RepoB;
}
public IAbstractFactoryA<T> CreateA()
{
if (RepoA == null)
return new AbstractFactoryA_Repository<T>();
else
return this.RepoA;
}
public IAbstractFactoryB<T> CreateB()
{
if (RepoA == null)
return new AbstractFactoryB_Repository<T>();
else
return RepoB;
}
}
Reference
What is the API gateway? An API gateway is an API management tool that sits…
The .NET 5 SDK is a kind of milestone in the .NET world. The .NET…
In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupling software…
In the field of software engineering, the interface segregation principle (ISP) states that no code…
Subtype Requirement: Let be a property provable about objects of type T. Then should be true for objects of type S where S is…
In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be…
View Comments