Please help me correct this code.
I am having a compiler error in the class
public interface IGenericSaveRepository
{
void Save<TEntity>(int id, ICollection<TEntity> entities) where TEntity : class;
}
public class GenericSaveRepository<TEntity> where TEntity : class,IGenericSaveRepository
{
private IUnitofWork<TEntity> _unitofWork;
private NaijaSchoolsContext _context;
public GenericSaveRepository(NaijaSchoolsContext context)
{
_context = context;
_unitofWork = new UnitofWork<TEntity>(_context);
}
public void Save(int id, ICollection<TEntity> entities)
{
foreach (var entity1 in entities)
{
//entity.Insert(entity1);
_unitofWork.Entity.Insert(entity1);
}
}
}
public class RatingRepo : GenericRepository<Rating>
{
private IGenericSaveRepository gen;
private readonly NaijaSchoolsContext _context;
public RatingRepo(NaijaSchoolsContext context)
: base(context)
{
_context = context;
}
public void Save(School school,Rating rating)
{
List<Rating> ratings = new List<Rating>();
ratings.Add(rating);
gen = new GenericSaveRepository<Rating>(_context);
gen.Save(23, ratings);
}
}
This line gen = new GenericSaveRepository<Rating>(_context); doesn't allow me to have Rating specified as a concrete type.
How can I do this?
Thanks for the help.
This should remove your compile error .. see gen implementation if you don't want Rating must implement IGenericSaveRepository
public class RatingRepo : GenericRepository<Rating>
{
private GenericSaveRepository<Rating> gen;
private readonly NaijaSchoolsContext _context;
public RatingRepo(NaijaSchoolsContext context)
: base(context)
{
_context = context;
}
public void Save(School school, Rating rating)
{
List<Rating> ratings = new List<Rating>();
ratings.Add(rating);
gen = new GenericSaveRepository<Rating>(_context);
gen.Save(23, ratings);
}
}
Update : Complete implementation
public interface IGenericSaveRepository
{
void Save<TEntity>(int id, ICollection<TEntity> entities) where TEntity : class;
}
public class GenericSaveRepository<TEntity> where TEntity : class
{
private UnitofWork<TEntity> _unitofWork;
private NaijaSchoolsContext _context;
public GenericSaveRepository(NaijaSchoolsContext context)
{
_context = context;
_unitofWork = new UnitofWork<TEntity>(_context);
}
public void Save(int id, ICollection<TEntity> entities)
{
foreach (var entity1 in entities)
{
}
}
}
public class UnitofWork<T>
{
public UnitofWork(NaijaSchoolsContext context)
{
throw new NotImplementedException();
}
}
internal interface IUnitofWork<T>
{
}
public class NaijaSchoolsContext
{
}
public class GenericRepository<T>
{
protected GenericRepository(NaijaSchoolsContext context)
{
throw new NotImplementedException();
}
}
public class Rating
{
}
public class School
{
}
Rating must implement IGenericSaveRepository in order for that to compile.
public class GenericSaveRepository<TEntity> where TEntity : class,IGenericSaveRepository
Related
I have more DbContext's. I want to use just one GenericRepository.
I try to create a GenericDbContextFactory. But how can I create TContext? What do I have to do, so the context is not null?
public class GenericRepository<TTable, TContext> : IGenericRepository<TTable, TContext>
where TTable : class
where TContext : DbContext
{
private TContext _context { get; set; } = default!;
private IGenericDbContextFactory _contextFactory;
private DbSet<TTable> _table { get; set; } = default!;
private readonly string _connectionString;
public GenericRepository(IGenericDbContextFactory contextFactory, string connectionString)
{
_connectionString = connectionString;
_contextFactory = contextFactory;
_context = GetNew();
}
public virtual void Reset()
{
_context.Dispose();
_context = GetNew();
}
public TContext GetNew()
{
var context = _contextFactory.Create(_connectionString) as TContext;
_table = context.Set<TTable>();
return context;
}
public async Task Save()
{
try
{
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
Reset();
throw new Exception(ex.Message);
}
_context.ChangeTracker.Clear();
}
public class GenericDbContextFactory : IGenericDbContextFactory
{
public DbContext Create(string connectionString)
{
if (!string.IsNullOrEmpty(connectionString))
{
var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
optionsBuilder.UseSqlServer(connectionString);
var context = new DbContext(optionsBuilder.Options);
return context;
}
else
{
throw new ArgumentNullException("ConnectionId");
}
}
}
GetNew return null (throw NullReferenceExceptioninstead?) because :
public TContext GetNew()
{
// GenericDbContextFactory.Create return GenericDbContext
GenericDbContext genericDbContext = _contextFactory.Create(_connectionString);
// GenericDbContext isn't TContext, then as operator return null
// context is set with null
var context = genericDbContext as TContext;
// throw NullReference Exception
_table = context.Set<TTable>();
return context;
}
To resolve this, you need GenericDbContextFactory.Create return TContext instance. But it isn't possible to have generic constrain with constructor parameters. One solution :
public class GenericRepository<TTable, TContext> : IGenericRepository<TTable, TContext>
where TTable : class
where TContext : GenericDbContext, new()
{
public TContext GetNew()
{
var context = _contextFactory.Create<TContext>(_connectionString);
_table = context.Set<TTable>();
return context;
}
...
}
public class GenericDbContextFactory : IGenericDbContextFactory
{
public TContext Create<TContext>(string connectionString) where TContext : GenericDbContext, new()
{
if (!string.IsNullOrEmpty(connectionString))
{
var context = new TContext();
context.Initialize(connectionString);
return context;
}
...
}
}
public abstract class GenericDbContext : DbContext
{
private string _connectionString;
public GenericDbContext()
{ }
public abstract void Initialize(string connectionString)
=> _connectionString = connectionString;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (string.IsNullOrEmpty(_connectionString))
throw new InvalidOperationException();
optionsBuilder.UseSqlServer(_connectionString);
}
}
You can found other possibilities in this other question :
Is there a generic constructor with parameter constraint in C#?
But please read carefully the remark of #PanagiotisKanavos. It's a really bad implementation of the repository pattern, because EF Core isn't hidden.
To use GenericRepository, it need to specify the real DbContext type and DbSet is raw exposed. With a good repository, you only manipulate the repository, without know what is under the hood.
In the majority of cases, EF Core can be use directly like a repository.
I am receiving null exception error on my framework. I have tried to apply Repository and Unit of Work design patterns in my application. What I am trying to do is simply retreiving user titles from my data base with GetAll() method.
Here is my repository class:
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
this.Context = context;
}
public T Get(int id)
{
return Context.Set<T>().Find(id);
}
public IEnumerable<T> GetAll()
{
return Context.Set<T>().ToList();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
{
return Context.Set<T>().Where(predicate);
}
public void Add(T entity)
{
Context.Set<T>().Add(entity);
}
public void AddRange(IEnumerable<T> entityList)
{
Context.Set<T>().AddRange(entityList);
}
public void Remove(T entity)
{
Context.Set<T>().Remove(entity);
}
public void RemoveRange(IEnumerable<T> entityList)
{
Context.Set<T>().RemoveRange(entityList);
}
}
This is IUserTitlesRepository:
public interface IUserTitlesRepository : IRepository<UserTitles>
{
}
And, the class where above interface implemented:
public UserTitlesRepository(XaPaDataContext context) : base(context)
{
}
public XaPaDataContext XaPaDataContext
{
get { return Context as XaPaDataContext; }
}
Before coming to Controller layer, I have two more layers, which are Operation and Manager layers. And, I think I have messed up on that part (on Base Manager class as shown below).
This is operation layer:
public class UserTitlesOperations
{
private readonly IUnitOfWork _uow;
public UserTitlesOperations(IUnitOfWork uow)
{
_uow = uow;
}
public List<UserTitles> GetAllUserTitles()
{
try
{
List<UserTitles> userTitleList = _uow.UserTitles.GetAll().ToList();
_uow.Complete();
return userTitleList;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
Below is the BaseManager class which gives inheritance to all manager classes.
public abstract class BaseManager
{
private IUnitOfWork _iUow;
private readonly XaPaDataContext _context;
public IUnitOfWork IUOW
{
get
{
if (_iUow == null)
{
_iUow = new XaPaUnitOfWork(_context);
}
return _iUow;
}
}
}
This is the manager class:
public class UserTitlesManager : BaseManager
{
private readonly UserTitlesOperations _userTitlesOperations;
public UserTitlesManager()
{
_userTitlesOperations = new UserTitlesOperations(base.IUOW);
}
public List<UserTitlesWM> GetAllUserTitles()
{
try
{
return UserTitlesMapping.MaptoWM(_userTitlesOperations.GetAllUserTitles());
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
Finally, this is my API Controller:
[Route("api/LoginRequest")]
public class TitlesController : BaseController
{
UserTitlesManager _userTitlesManager;
public LoginController()
{
_userTitlesManager = new UserTitlesManager();
}
[Route("RetreiveTitles")]
public HttpResponseMessage GetTitles()
{
try
{
return Request.CreateResponse(HttpStatusCode.OK, _userTitlesManager.GetAllUserTitles());
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.ToString());
}
}
}
By the way BaseController is just another API controller which gives inheritance to all other API controllers, and houses a method which is used by all the other controllers.
So, I'm still trying to sharpen my self on this design patterns and would be glad if anyone could show my mistake on BaseManager class. As I said, I suppose the problem is caused by that private readonly XaPaDataContext _context; line. On the other hand,I can't figure out how to corrrect it as my operation classes' constructors are asking for IUnitOfWork.
Thank you in advance!
EDIT:
Just realized that I forgot to share my Unit of Work class:
public class XaPaUnitOfWork : IUnitOfWork
{
private readonly XaPaDataContext _context;
public XaPaUnitOfWork(XaPaDataContext context)
{
_context = context;
Categories = new CategoriesRepository(_context);
OrderDetails = new OrderDetailsRepository(_context);
Orders = new OrdersRepository(_context);
ProductImages = new ProductImagesRepository(_context);
Products = new ProductsRepository(_context);
Users = new UsersRepository(_context);
UserTitles = new UserTitlesRepository(_context);
UserTokens = new UserTokensRepository(_context);
}
public ICategoriesRepository Categories { get; private set; }
public IOrderDetailsRepository OrderDetails { get; private set; }
public IOrdersRepository Orders { get; private set; }
public IProductImagesRepository ProductImages { get; private set; }
public IProductsRepository Products { get; private set; }
public IUsersRepository Users { get; private set; }
public IUserTitlesRepository UserTitles { get; private set; }
public IUserTokensRepository UserTokens { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
After I have changed my BaseManager class as below:
public abstract class BaseManager
{
private IUnitOfWork _iUow;
public IUnitOfWork IUOW
{
get
{
if (_iUow == null)
{
_iUow = new XaPaUnitOfWork(new XaPaDataContext());
}
return _iUow;
}
}
}
I have achived to receive HttpStatusCode.OK
But, honestly, I'm still unsure about the real reason. I make this correction mostly by heart.
I have a simple generic repository.
In this Repository, I have a generic DBContext and thats means its not specific to my appliktion.
The generic DbContext are still able to access my DBcontexts Entites, such
Context.Set<TEntity>().Add(entity)
Do the method Set() here geting reference to my webapplikationens DBContext, or what is happening ?
Full Code:
public interface IRepository<TEntity> where TEntity : class
{
TEntity Get(int id);
void Add(TEntity entity);
}
...
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public TEntity Get(int id)
{
// Here we are working with a DbContext, not PlutoContext. So we don't have DbSets
// such as Courses or Authors, and we need to use the generic Set() method to access them.
//Returns a non-generic DbSet instance for access to entities of the given type in the context and the underlying store .
return Context.Set<TEntity>().Find(id);
}
public void Add(TEntity entity)
{
Context.Set<TEntity>().Add(entity);
}
}
.................................
public interface IAuthorRepository : IRepository<Author>
{
Author GetAuthorWithCourses(int id);
}
..
public class AuthorRepository : Repository<Author>, IAuthorRepository
{
public AuthorRepository(PlutoContext context) : base(context)
{
}
public Author GetAuthorWithCourses(int id)
{
return PlutoContext.Authors.Include(a => a.Courses).SingleOrDefault(a => a.Id == id);
}
public PlutoContext PlutoContext
{
get { return Context as PlutoContext; }
}
}
..
public interface IUnitOfWork : IDisposable
{
IAuthorRepository Authors { get; }
int Complete();
}
...
public class UnitOfWork : IUnitOfWork
{
private readonly PlutoContext _context;
public UnitOfWork(PlutoContext context)
{
_context = context;
Authors = new AuthorRepository(_context);
}
public IAuthorRepository Authors { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
...
public class Repository<Entity> : IRepository<Entity> where Entity : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public void Add(Entity entity)
{
Context.Set<TEntity>().Add(entity);
}
}
The argument DbContext context is just a compile-time type, the actual type of the parameter isn't changed.
The code below seems to work using this:
var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider();
var repository = new FakeRepository();
var fake = new Fake
{
// etc.
};
using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString"))
{
repository.Insert(uow, fake);
uow.Commit();
}
which may eventually move into a service layer. I would appreciate any feedback to improve this code.
public interface IUnitOfWork : IDisposable
{
void Commit();
Database Database { get; }
}
public interface IUnitOfWorkProvider
{
IUnitOfWork GetUnitOfWork(string connectionString);
}
public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
public IUnitOfWork GetUnitOfWork(string connectionString)
{
return new PetaPocoUnitOfWork(connectionString);
}
}
public interface IRepository<T>
{
void Insert(IUnitOfWork unitOfWork, T entity);
void Update(IUnitOfWork unitOfWork, T entity);
void Delete(IUnitOfWork unitOfWork, T entity);
T Fetch(IUnitOfWork unitOfWork, long uid);
}
public class PetaPocoUnitOfWork : IUnitOfWork
{
private readonly Transaction _petaTransaction;
private readonly Database _database;
public PetaPocoUnitOfWork(string connectionString)
{
_database = new Database(connectionString);
_petaTransaction = new Transaction(_database);
}
public void Dispose()
{
_petaTransaction.Dispose();
}
public Database Database
{
get { return _database; }
}
public void Commit()
{
_petaTransaction.Complete();
}
}
public class FakeRepository : IRepository<Fake>
{
public void Insert(IUnitOfWork unitOfWork, Fake entity)
{
unitOfWork.Database.Save(entity);
}
public void Update(IUnitOfWork unitOfWork, Fake entity)
{
unitOfWork.Database.Update(entity);
}
public void Delete(IUnitOfWork unitOfWork, Fake entity)
{
unitOfWork.Database.Delete(entity);
}
public FakeJobFact Fetch(IUnitOfWork unitOfWork, long uid)
{
return unitOfWork.Database.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = #0", uid).FirstOrDefault();
}
}
PS:
I have adapted the code according to #Plebsori current answer:
public abstract class BaseRepository<T>
{
protected IDatabase Database
{
get
{
return UnitOfWork.Current;
}
}
public void Insert(T entity)
{
Database.Save(entity);
}
public void Update(T entity)
{
Database.Update(entity);
}
public void Delete(T entity)
{
Database.Delete(entity);
}
}
public interface IRepository<T>
{
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
T Fetch(long uid);
}
public interface IUnitOfWork : IDisposable
{
void Commit();
Database Database { get; }
}
public interface IUnitOfWorkProvider
{
IUnitOfWork GetUnitOfWork(string connectionString);
}
public class PetaPocoUnitOfWork : IUnitOfWork
{
private readonly Transaction _petaTransaction;
private readonly Database _database;
public PetaPocoUnitOfWork(string connectionString)
{
_database = new Database(connectionString);
_petaTransaction = new Transaction(_database);
}
public void Dispose()
{
UnitOfWork.Current = null;
_petaTransaction.Dispose();
}
public Database Database
{
get { return _database; }
}
public void Commit()
{
_petaTransaction.Complete();
}
}
public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
public IUnitOfWork GetUnitOfWork(string connectionString)
{
if (UnitOfWork.Current != null)
{
throw new InvalidOperationException("Existing unit of work.");
}
var petaPocoUnitOfWork = new PetaPocoUnitOfWork(connectionString);
UnitOfWork.Current = petaPocoUnitOfWork.Database;
return petaPocoUnitOfWork;
}
}
public static class UnitOfWork
{
[ThreadStatic] public static IDatabase Current;
}
You may or may not like, but here's how I removed the passing of unit of work and the unit of work from the interface.
var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider();
var repository = new FakeRepository();
var fake = new Fake
{
// etc.
};
using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString"))
{
repository.Insert(fake);
uow.Commit();
}
Code
public interface IUnitOfWorkProvider
{
IUnitOfWork GetUnitOfWork(string connectionString);
}
public static class UnitOfWork
{
[ThreadStatic]
public static IUnitOfWork Current { get; set; }
}
public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
public IUnitOfWork GetUnitOfWork(string connectionString)
{
if (UnitOfWork.Current != null)
{
throw new InvalidOperationException("Existing unit of work.");
}
UnitOfWork.Current = new PetaPocoUnitOfWork(connectionString);
return UnitOfWork.Current;
}
}
public interface IRepository<T>
{
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
T Fetch(long uid);
}
public class PetaPocoUnitOfWork : IUnitOfWork
{
private readonly Transaction _petaTransaction;
private readonly Database _database;
public PetaPocoUnitOfWork(string connectionString)
{
_database = new Database(connectionString);
_petaTransaction = new Transaction(_database);
}
public void Dispose()
{
UnitOfWork.Current = null;
_petaTransaction.Dispose();
}
public Database Database
{
get { return _database; }
}
public void Commit()
{
_petaTransaction.Complete();
}
}
public abstract class BaseRepository<T> : IRepository<T>
{
protected IDatabase Db
{
get
{
return UnitOfWork.Current;
}
}
}
public class FakeRepository : BaseRepository<T>
{
public void Insert(Fake entity)
{
Db.Save(entity);
}
public void Update(Fake entity)
{
Db.Update(entity);
}
public void Delete(Fake entity)
{
Db.Delete(entity);
}
public FakeJobFact Fetch(long uid)
{
return Db.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = #0", uid).FirstOrDefault();
}
}
Say I have the following implementation:
//Generic repository.
public interface IRepository<T> where T : class {
void Insert(T entity);
void Delete(int id);
void SaveChanges();
//..more generic functions
}
//Repository implementation.
public class EFRepository<T> : IRepository<T> where T: class {
private MyDbContext context;
protected DbSet<T> dbSet;
public EFRepository(): this(new MyDbContext()){}
public EFRepository(MyDbContext context)
{
this.context = context;
dbSet = context.Set<T>();
}
public void Insert(T entity)
{
dbSet.Add(entity);
}
public void Delete(int id)
{
dbSet.Remove(dbSet.Find(id));
}
public void SaveChanges()
{
context.SaveChanges();
}
//...more generic implementations
}
//Unit of Work Interface
public interface IUnitOfWork: IDisposable
{
IRepository<EntityA> ARepository { get; }
IRepository<EntityB> BRepository { get; }
//...more stuff
}
//Unit of Work Implementation
public class EFUnitOfWork: IUnitOfWork
{
private MyDbContext context = new MyDbContext();
private IRepository<EntityA> aRepository;
private IRepository<EntityB> bRepository;
public IRepository<EntityA> ARepository
{
get
{
if (this.aRepository == null)
this.aRepository = new EFRepository<EntityA>(context);
return this.aRepository;
}
}
public IRepository<EntityB> BRepository
{
get
{
if (this.bRepository == null)
this.bRepository = new EFRepository<EntityB>(context);
return this.bRepository;
}
}
//...more stuff
}
And finally, I have the following bindings in my resolver:
kernel.Bind(typeof(IRepository<>)).To(typeof(EFRepository<>));
kernel.Bind(typeof(IUnitOfWork)).To(typeof(EFUnitOfWork));
Now, my question is... how would I go about extending the repository for EntityA so that it has more operations than just the generic ones?
I'll post what I have so far in a few...
EDIT: Here's what I have so far:
//New interface.
public class IEntityARepository : IRepository<EntityA>
{
void DoSomethingSpecificToEntityA();
}
//New implementation.
public class EFEntityARepository : EFRepository<EntityA>
{
public EFEntityARepository(MyDbContext context) : base(context) {}
//add additional methods for EntityA
public void DoSomethingSpecificToEntityA()
{
}
}
//Modify Unit of Work Interface as follows.
//Unit of Work Interface
public interface IUnitOfWork: IDisposable
{
IEntityARepository ARepository { get; }
IRepository<EntityB> BRepository { get; }
//...more stuff
}
//Modify Unit of Work Implementation as follows.
public class EFUnitOfWork: IUnitOfWork
{
private MyDbContext context = new MyDbContext();
private IEntityARepository aRepository;
private IRepository<EntityB> bRepository;
public IEntityARepository ARepository
{
get
{
if (this.aRepository == null)
this.aRepository = new EFEntityARepository<EntityA>(context);
return this.aRepository;
}
}
public IRepository<EntityB> BRepository
{
get
{
if (this.bRepository == null)
this.bRepository = new EFRepository<EntityB>(context);
return this.bRepository;
}
}
//...more stuff
}
Add the following binding:
kernel.Bind(typeof(IEntityARepository)).To(typeof(EFEntityARepository));
However, I'm sure this is not correct. Or at least, not the proper way to do it.
If I understand you correctly, you could just derrive from a specifically typed version of your generic class like this...
public class EFEntityARepository : EFRepository<EntityA>, IEntityARepository
{
//Add more opps
}
I think the unit of work needs to look like this:
public IEntityARepository ARepository
{
get
{
if (this.aRepository == null)
this.aRepository = new EFEntityARepository(context);
return this.aRepository;
}
}
OK so I've got it working by adding and/or modifying my original code as follows:
//New interface for the extension of the repository.
//Is it possible to do this without defining this new interface? Doesn't seem like it.
public class IEntityARepository : IRepository<EntityA>
{
void DoSomethingSpecificToEntityA();
}
//Add new class.
//It looks like you have to inherit from IEntityARepository as well.
public class EFEntityARepository : EFRepository<EntityA>, IEntityARepository
{
public EFEntityARepository(MyDbContext context) : base(context) {}
//add additional methods for EntityA
public void DoSomethingSpecificToEntityA()
{
}
}
//Modify Unit of Work Interface as follows.
public interface IUnitOfWork: IDisposable
{
IEntityARepository ARepository { get; }
IRepository<EntityB> BRepository { get; }
//...more stuff
}
//Modify Unit of Work Implementation as follows.
public class EFUnitOfWork: IUnitOfWork
{
private MyDbContext context = new MyDbContext();
private IEntityARepository aRepository;
private IRepository<EntityB> bRepository;
public IEntityARepository ARepository
{
get
{
if (this.aRepository == null)
this.aRepository = new EFEntityARepository(context);
return this.aRepository;
}
}
public IRepository<EntityB> BRepository
{
get
{
if (this.bRepository == null)
this.bRepository = new EFRepository<EntityB>(context);
return this.bRepository;
}
}
//...more stuff
}
It works... but is it the best way to go about it?