Posted
over 10 years
ago
We have finally released v1.5 of MVCForum - You can download the
binaries and source from Codeplex
https://themvcforum.codeplex.com
Quite a bit of time went into this version, and there were a lot
of changes. The list below highlights some of
... [More]
the main ones. As
always, if you have any questions or queries please use our support
forum.
Loads of bug fixes
Upgraded to MVC5 and EF6.1
New second level caching provider
Moderate Topics & Posts (Optional)
Updated editors (TinyMCE, Markdown, BBCode) and made it easier
to swap them
Screenr Embedding into posts
Sent and received messages now seperate
All Repos, Services, Models, Interfaces, ViewModels made
partial for easier extending
Install SQL changed to work on Azure
Installer updated to make it more robust and more useful error
messages
Category Page Title, Meta Description and HTML Editor for
description added
Points awarded for badges
Language Selector (Change front end language)
Badges split into own badges/dll's - So you can remove specific
badges
3 new badges added (The Grough, Padawan, Thousand Pointer)
Breadcrumb Navigation and Category Paths added
Updated Category admin page to make it easier to use
Page Title & Meta Description added to Forum home page
Quote button added
OG Meta tags / Twitter card tags added
Optional show latest posts OR/And full category list on home
page (Just uncomment)
Members can now upload new Avatars instead of just using
Gravatar
Views are now bundled with Themes, no more default views
Google XML Sitemap
Two language packs added (German & Persian)
Updated social sharing buttons on topics
We look forward to all feedback. Thanks. [Less]
|
Posted
over 10 years
ago
We have finally released v1.5 of MVCForum - You can download the
binaries and source from Codeplex
https://themvcforum.codeplex.com
Quite a bit of time went into this version, and there were a lot
of changes. The list below highlights some of the
... [More]
main ones. As
always, if you have any questions or queries please use our support
forum.
Loads of bug fixes
Upgraded to MVC5 and EF6.1
New second level caching provider
Moderate Topics & Posts (Optional)
Updated editors (TinyMCE, Markdown, BBCode) and made it easier
to swap them
Screenr Embedding into posts
Sent and received messages now seperate
All Repos, Services, Models, Interfaces, ViewModels made
partial for easier extending
Install SQL changed to work on Azure
Installer updated to make it more robust and more useful error
messages
Category Page Title, Meta Description and HTML Editor for
description added
Points awarded for badges
Language Selector (Change front end language)
Badges split into own badges/dll's - So you can remove specific
badges
3 new badges added (The Grough, Padawan, Thousand Pointer)
Breadcrumb Navigation and Category Paths added
Updated Category admin page to make it easier to use
Page Title & Meta Description added to Forum home page
Quote button added
OG Meta tags / Twitter card tags added
Optional show latest posts OR/And full category list on home
page (Just uncomment)
Members can now upload new Avatars instead of just using
Gravatar
Views are now bundled with Themes, no more default views
Google XML Sitemap
Two language packs added (German & Persian)
Updated social sharing buttons on topics
We look forward to all feedback. Thanks.
[Less]
|
Posted
about 11 years
ago
I'm happy to say we have finally released v1.4 of MVCforum. A
lot of time and effort has gone into this release to try and make
the forums even more usable, and also fix all the bugs that were
reported. Any feedback is very welcome.
Codeplex
... [More]
download
Application: https://themvcforum.codeplex.com
Source:
https://themvcforum.codeplex.com/SourceControl/list/changesets
Web Platform Installer
Submitted - Awaiting them to publish it (Probably a couple
of days)
In this release we concentrated on the
following:
Responsive Layouts - No more dedicated mobile themes * just
responsive themes using Bootstrap.
Admin Updated - Updated UI and 95% responsive, ran out of time
to finish a few pages.
New Dark Theme & Jungle Theme (Now comes with 4 different
themes OOTB)
IP address stored per post and displayed to admins
Option to have Email confirmation on register option (Member
has to click a link in email to confirm account)
Google login to use username instead of email for forum
username
Social media shares to topics added
Easier to message other members
Canonical Tags added to topics for SEO
Updated Markdown Editor
Main website update (Coming in the next week)
Updated installer and upgrader - Hopefully handle errors better
and give users more information
Loads of minor bug fixes and UI
enhancements
* = Although one little gem is a custom class on the body tag.
If its a desktop machine the body tag will have a class of
'desktop' and if it's a mobile device it will have a class of
'mobile' so you can still make specific changes purely for a mobile
device whatever the screen size.
Dark Theme
Jungle Theme
[Less]
|
Posted
about 11 years
ago
I'm happy to say we have finally released v1.4 of MVCforum. A
lot of time and effort has gone into this release to try and make
the forums even more usable, and also fix all the bugs that were
reported. Any feedback is very welcome.
Codeplex
... [More]
download
Application: https://themvcforum.codeplex.com
Source:
https://themvcforum.codeplex.com/SourceControl/list/changesets
Web Platform Installer
Submitted - Awaiting them to publish it (Probably a couple
of days)
In this release we concentrated on the
following:
Responsive Layouts - No more dedicated mobile themes * just
responsive themes using Bootstrap.
Admin Updated - Updated UI and 95% responsive, ran out of time
to finish a few pages.
New Dark Theme & Jungle Theme (Now comes with 4 different
themes OOTB)
IP address stored per post and displayed to admins
Option to have Email confirmation on register option (Member
has to click a link in email to confirm account)
Google login to use username instead of email for forum
username
Social media shares to topics added
Easier to message other members
Canonical Tags added to topics for SEO
Updated Markdown Editor
Main website update (Coming in the next week)
Updated installer and upgrader - Hopefully handle errors better
and give users more information
Loads of minor bug fixes and UI
enhancements
* = Although one little gem is a custom class on the body tag.
If its a desktop machine the body tag will have a class of
'desktop' and if it's a mobile device it will have a class of
'mobile' so you can still make specific changes purely for a mobile
device whatever the screen size.
Dark Theme
Jungle Theme
[Less]
|
Posted
about 11 years
ago
I'm happy to say we have finally released v1.4 of MVCforum. A
lot of time and effort has gone into this release to try and make
the forums even more usable, and also fix all the bugs that were
reported. Any feedback is very welcome.
Codeplex
... [More]
download
Application: https://themvcforum.codeplex.com
Source:
https://themvcforum.codeplex.com/SourceControl/list/changesets
Web Platform Installer
Submitted - Awaiting them to publish it (Probably a couple
of days)
In this release we concentrated on the
following:
Responsive Layouts - No more dedicated mobile themes * just
responsive themes using Bootstrap.
Admin Updated - Updated UI and 95% responsive, ran out of time
to finish a few pages.
New Dark Theme & Jungle Theme (Now comes with 4 different
themes OOTB)
IP address stored per post and displayed to admins
Option to have Email confirmation on register option (Member
has to click a link in email to confirm account)
Google login to use username instead of email for forum
username
Social media shares to topics added
Easier to message other members
Canonical Tags added to topics for SEO
Updated Markdown Editor
Main website update (Coming in the next week)
Updated installer and upgrader - Hopefully handle errors better
and give users more information
Loads of minor bug fixes and UI
enhancements
* = Although one little gem is a custom class on the body tag.
If its a desktop machine the body tag will have a class of
'desktop' and if it's a mobile device it will have a class of
'mobile' so you can still make specific changes purely for a mobile
device whatever the screen size.
Dark Theme
Jungle Theme
[Less]
|
Posted
over 11 years
ago
Its been a long time in the coming, but we have finally shipped
v1.3. And I have to say we are pretty proud of this version, as its
been the most tested and bug fixed version to date.
There were so many changes in v1.3 it's been hard to keep track.
... [More]
But due to some of the changes, this version doesn't have an auto
upgrade path like v1.1 to v1.2 had. The installer had a massive
rewrite to which made the auto upgrade difficult, as well as a lot
of changes to the database and config files.
However, as always you can manually upgrade. We keep track of
all changes made in the following file in the solution (Just
scroll down to v1.3) Database >
VersionDbChanges.txt.
Here's a list of most of the changes
Loads of bug fixes & UI tweaks
Installer rewrite
Import language rewrite, now auto updates and inserts via a
CSV
File attachments to posts
New permissions (Create topic, Upload Files)
New social logins (Twitter, Google & Yahoo)
Disable options on a per user basis
Banned Word filter
Bootstrap Syntax highlighting
Ajax show more comments
Sort comments (Standard, Newest & Highest Voted)
Choice of editors (RTE's) OOTB - MarkDown, TinyMCE & BBEditor
Banned Emails/Domains
Updated Themes & Mobile styles/layout
Updated mobile/tablet targeting
Who's online
Batch delete members
Batch move topics
Updated design/code for email notification template
Email notification for private messages
New show positive and negative for post points (On click)
StackOverFlow inspired 'Questions that may already have your
answer'
Suspend registration of new members
Polls updated and improved
New permanent Moderator role, moderators can ban members and
delete posts etc…
And loads of other minor changes based of everyone's
feedback….
[Less]
|
Posted
over 11 years
ago
Its been a long time in the coming, but we have finally shipped
v1.3. And I have to say we are pretty proud of this version, as its
been the most tested and bug fixed version to date.
There were so many changes in v1.3 it's been hard to keep track.
... [More]
But due to some of the changes, this version doesn't have an auto
upgrade path like v1.1 to v1.2 had. The installer had a massive
rewrite to which made the auto upgrade difficult, as well as a lot
of changes to the database and config files.
However, as always you can manually upgrade. We keep track of
all changes made in the following file in the solution (Just
scroll down to v1.3) Database >
VersionDbChanges.txt.
Here's a list of most of the changes
Loads of bug fixes & UI tweaks
Installer rewrite
Import language rewrite, now auto updates and inserts via a
CSV
File attachments to posts
New permissions (Create topic, Upload Files)
New social logins (Twitter, Google & Yahoo)
Disable options on a per user basis
Banned Word filter
Bootstrap Syntax highlighting
Ajax show more comments
Sort comments (Standard, Newest & Highest Voted)
Choice of editors (RTE's) OOTB - MarkDown, TinyMCE & BBEditor
Banned Emails/Domains
Updated Themes & Mobile styles/layout
Updated mobile/tablet targeting
Who's online
Batch delete members
Batch move topics
Updated design/code for email notification template
Email notification for private messages
New show positive and negative for post points (On click)
StackOverFlow inspired 'Questions that may already have your
answer'
Suspend registration of new members
Polls updated and improved
New permanent Moderator role, moderators can ban members and
delete posts etc…
And loads of other minor changes based of everyone's
feedback….
[Less]
|
Posted
over 11 years
ago
Its been a long time in the coming, but we have finally shipped
v1.3. And I have to say we are pretty proud of this version, as its
been the most tested and bug fixed version to date.
There were so many changes in v1.3 it's been hard to keep
... [More]
track.
But due to some of the changes, this version doesn't have an auto
upgrade path like v1.1 to v1.2 had. The installer had a massive
rewrite to which made the auto upgrade difficult, as well as a lot
of changes to the database and config files.
However, as always you can manually upgrade. We keep track of
all changes made in the following file in the solution (Just
scroll down to v1.3) Database >
VersionDbChanges.txt.
Here's a list of most of the changes
Loads of bug fixes & UI tweaks
Installer rewrite
Import language rewrite, now auto updates and inserts via a
CSV
File attachments to posts
New permissions (Create topic, Upload Files)
New social logins (Twitter, Google & Yahoo)
Disable options on a per user basis
Banned Word filter
Bootstrap Syntax highlighting
Ajax show more comments
Sort comments (Standard, Newest & Highest Voted)
Choice of editors (RTE's) OOTB - MarkDown, TinyMCE & BBEditor
Banned Emails/Domains
Updated Themes & Mobile styles/layout
Updated mobile/tablet targeting
Who's online
Batch delete members
Batch move topics
Updated design/code for email notification template
Email notification for private messages
New show positive and negative for post points (On click)
StackOverFlow inspired 'Questions that may already have your
answer'
Suspend registration of new members
Polls updated and improved
New permanent Moderator role, moderators can ban members and
delete posts etc…
And loads of other minor changes based of everyone's
feedback….
[Less]
|
Posted
over 11 years
ago
I have been asked a few times on how to create your own table
and add it into MVCForum. I have already created a blog about adding your own custom
table and this is a follow up to that post.
In the previous post we created a table called
BannedWord
... [More]
and created a domain class of the same
name and mapped it to the database. You can now query that table
from within an existing repository that has a context. But its not
an ideal situation, as we have tried to create a very DDD pattern and allow you to be able to swap
out services and repos with ease just by changing a couple of lines
in the IOC container.
In the current application we have a
BannedWordService and a
BannedWordRepository and in the post below I'll
explain how I added them and use them, so you can do the same for
you own custom table/Domain model and keep the same structure as
you customise your own forum.
Before you delve in, I must say. When I first started developing
this way, I thought it was so long winded. But now after using it
for a while I can see how beneficial it is and its pretty quick to
setup after you have done it a few times.
Interfaces
First thing we need to do is create a couple of interfaces
within the MVCForum.Domain > Interfaces section. One for the
Service and one for the Repository (Repo). Then within these
interfaces we will add in the method signatures that we think we'll
need to use.
Don't worry you can always add more later down the line (In fact
I pretty much always end up adding another one or two). The methods
you add are usually just CRUD methods.
MVCForum.Domain > Interfaces > Repositories
This is where we create the Repo interface and you prefix all
interfaces with IYourDomainName. Here is the
IBannedWordRepository.
using System;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
namespace MVCForum.Domain.Interfaces.Repositories
{
public interface IBannedWordRepository
{
BannedWord Add(BannedWord bannedWord);
void Delete(BannedWord bannedWord);
IList<BannedWord> GetAll();
BannedWord Get(Guid id);
PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize);
PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize);
}
}
MVCForum.Domain > Interfaces > Services
And here is the IBannedWordService I have added. You'll see the
methods are pretty much the same as the Repo. Around 95% of the
time it will be the same as the repo, but I'll go into more detail
further down about the difference between the two.
using System;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
namespace MVCForum.Domain.Interfaces.Services
{
public interface IBannedWordService
{
BannedWord Add(BannedWord bannedWord);
void Delete(BannedWord bannedWord);
IList<BannedWord> GetAll();
BannedWord Get(Guid id);
PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize);
PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize);
string SanitiseBannedWords(string content);
string SanitiseBannedWords(string content, IList<string> words);
}
}
Implementing The Interfaces (Creating the Service &
Repo)
Now we have created both the above interfaces, we can implement
them in the appropriate places. If you don't know about interfaces
and how to implement them, then I really suggest you have a read up
online.
However in short, its very simple and just a matter of creating
a class i.e. BannedWordRepository and then at the top of the class
next to the class name. You just add a colon : and
then interface name (i.e. public class BannedWordRepository
: IBannedWordRepository) then visual studio will pick up
on this and hopefully prompt you and create the method stubs for
you.
MVCForum.Data > Repositories
We'll create the repo first. BUT one thing you will notice. In
pretty much every repo, we add a Constructor and within that add
the context (The context is how we query the DBsets/Domain models
via
Entity Framework). This is resolved by IOC (See below) so you
can get access to the database. Don't forget to add/update this or
you won't be able to query the data as no context will exist.
using System;
using System.Collections.Generic;
using System.Linq;
using MVCForum.Data.Context;
using MVCForum.Domain.DomainModel;
using MVCForum.Domain.Interfaces;
using MVCForum.Domain.Interfaces.Repositories;
namespace MVCForum.Data.Repositories
{
public class BannedWordRepository : IBannedWordRepository
{
private readonly MVCForumContext _context;
public BannedWordRepository(IMVCForumContext context)
{
_context = context as MVCForumContext;
}
public BannedWord Add(BannedWord bannedWord)
{
return _context.BannedWord.Add(bannedWord);
}
public void Delete(BannedWord bannedWord)
{
_context.BannedWord.Remove(bannedWord);
}
public IList<BannedWord> GetAll()
{
return _context.BannedWord.OrderByDescending(x => x.DateAdded).ToList();
}
public BannedWord Get(Guid id)
{
return _context.BannedWord.FirstOrDefault(x => x.Id == id);
}
public PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize)
{
var total = _context.BannedWord.Count();
var results = _context.BannedWord
.OrderBy(x => x.Word)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedList<BannedWord>(results, pageIndex, pageSize, total);
}
public PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize)
{
var total = _context.BannedWord.Count(x => x.Word.ToLower().Contains(search.ToLower()));
var results = _context.BannedWord
.Where(x => x.Word.ToLower().Contains(search.ToLower()))
.OrderBy(x => x.Word)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedList<BannedWord>(results, pageIndex, pageSize, total);
}
}
}
MVCForum.Data > MVCForum.Services
Now we add the service. And again as with the context in the
constructor of the Repo. This time, in the constructor of the class
we pull in the Repo we just created so we can get access to the
data.
The difference between the two classes is like this. The Repo
should be purely for getting data and returning it. The service is
for getting the data and then doing any complicated logic before it
passes it on (i.e. Remapping, filtering, sanitising content etc…).
So here is our Service.
using System;
using System.Linq;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
using MVCForum.Domain.Interfaces.Repositories;
using MVCForum.Domain.Interfaces.Services;
using MVCForum.Utilities;
namespace MVCForum.Services
{
public class BannedWordService : IBannedWordService
{
private readonly IBannedWordRepository _bannedWordRepository;
public BannedWordService(IBannedWordRepository bannedWordRepository)
{
_bannedWordRepository = bannedWordRepository;
}
public BannedWord Add(BannedWord bannedWord)
{
return _bannedWordRepository.Add(bannedWord);
}
public void Delete(BannedWord bannedWord)
{
_bannedWordRepository.Delete(bannedWord);
}
public IList<BannedWord> GetAll()
{
return _bannedWordRepository.GetAll();
}
public BannedWord Get(Guid id)
{
return _bannedWordRepository.Get(id);
}
public PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize)
{
return _bannedWordRepository.GetAllPaged(pageIndex, pageSize);
}
public PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize)
{
return _bannedWordRepository.GetAllPaged(search, pageIndex, pageSize);
}
public string SanitiseBannedWords(string content)
{
var bannedWords = GetAll();
if (bannedWords.Any())
{
return SanitiseBannedWords(content, bannedWords.Select(x => x.Word).ToList());
}
return content;
}
public string SanitiseBannedWords(string content, IList<string> words)
{
if (words != null && words.Any())
{
var censor = new CensorUtils(words);
return censor.CensorText(content);
}
return content;
}
}
}
You'll notice at the bottom there is a CensorUtils class. This
is something that is added in v1.3 to the forum. If you are
following this word for word, then just remove both
SanitiseBannedWords methods from the interface and implementation
as you won't need them for this tutorial.
Registering With The IOC Container
Once you have created both your Service and Repository you need
to register them in with the IOC container (We currently use
Unity for our IoC), or the repo in the service constructor
above won't work and you won't be able to use your service in the
controllers.
MVCForum.IOC > UnityMVC3.cs
This is a really simple couple of lines to add. Just open the
above file and add in the following for the service and repo.
container.BindInRequestScope<IBannedWordService, BannedWordService>();
container.BindInRequestScope<IBannedWordRepository, BannedWordRepository>();
It should be pretty self explanatory where to add these, the
services are all grouped together and so are the repos. All this
file does it point the interface to which implementation of the
interface to use. So you can swap out implementations top custom
ones if you want to.
Using The Service In A Controller
As you will see throughout and I mentioned above. The repo is
never used apart from by the services. They simply just
transfer/update/delete data from the database. But the services are
what you use and call from within the application.
So to get the data back and use what we have just created, we
need to call the service from your controller. This is very simple
and the same as how we called the Repo from within our service. We
just setup a constructor and initialise the service interface we
want to use and the IOC container will take care of the rest and
get the correct implementation.
For example. If I wanted to create a
BannedWordController then I would set it up like
this with the service in the constructor
using System.Web.Mvc;
using MVCForum.Domain.Interfaces.Services;
namespace MVCForum.Website.Controllers
{
public class BannedWordController : Controller
{
private readonly IBannedWordService _bannedWordService;
public BannedWordController(IBannedWordService bannedWordService)
{
_bannedWordService = bannedWordService;
}
public ActionResult Index()
{ // I can now use the service here by called
var getAllBannedWords = _bannedWordService.GetAll(); return View();
}
}
}
And that's it. We can call the service from any controller we
want as long as we set it up in the constructor like the above
example.
[Less]
|
Posted
over 11 years
ago
I have been asked a few times on how to create your own table
and add it into MVCForum. I have already created a blog about adding your own custom
table and this is a follow up to that post.
In the previous post we created a table called
BannedWord
... [More]
and created a domain class of the same
name and mapped it to the database. You can now query that table
from within an existing repository that has a context. But its not
an ideal situation, as we have tried to create a very DDD pattern and allow you to be able to swap
out services and repos with ease just by changing a couple of lines
in the IOC container.
In the current application we have a
BannedWordService and a
BannedWordRepository and in the post below I'll
explain how I added them and use them, so you can do the same for
you own custom table/Domain model and keep the same structure as
you customise your own forum.
Before you delve in, I must say. When I first started developing
this way, I thought it was so long winded. But now after using it
for a while I can see how beneficial it is and its pretty quick to
setup after you have done it a few times.
Interfaces
First thing we need to do is create a couple of interfaces
within the MVCForum.Domain > Interfaces section. One for the
Service and one for the Repository (Repo). Then within these
interfaces we will add in the method signatures that we think we'll
need to use.
Don't worry you can always add more later down the line (In fact
I pretty much always end up adding another one or two). The methods
you add are usually just CRUD methods.
MVCForum.Domain > Interfaces > Repositories
This is where we create the Repo interface and you prefix all
interfaces with IYourDomainName. Here is the
IBannedWordRepository.
using System;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
namespace MVCForum.Domain.Interfaces.Repositories
{
public interface IBannedWordRepository
{
BannedWord Add(BannedWord bannedWord);
void Delete(BannedWord bannedWord);
IList<BannedWord> GetAll();
BannedWord Get(Guid id);
PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize);
PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize);
}
}
MVCForum.Domain > Interfaces > Services
And here is the IBannedWordService I have added. You'll see the
methods are pretty much the same as the Repo. Around 95% of the
time it will be the same as the repo, but I'll go into more detail
further down about the difference between the two.
using System;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
namespace MVCForum.Domain.Interfaces.Services
{
public interface IBannedWordService
{
BannedWord Add(BannedWord bannedWord);
void Delete(BannedWord bannedWord);
IList<BannedWord> GetAll();
BannedWord Get(Guid id);
PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize);
PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize);
string SanitiseBannedWords(string content);
string SanitiseBannedWords(string content, IList<string> words);
}
}
Implementing The Interfaces (Creating the Service &
Repo)
Now we have created both the above interfaces, we can implement
them in the appropriate places. If you don't know about interfaces
and how to implement them, then I really suggest you have a read up
online.
However in short, its very simple and just a matter of creating
a class i.e. BannedWordRepository and then at the top of the class
next to the class name. You just add a colon : and
then interface name (i.e. public class BannedWordRepository
: IBannedWordRepository) then visual studio will pick up
on this and hopefully prompt you and create the method stubs for
you.
MVCForum.Data > Repositories
We'll create the repo first. BUT one thing you will notice. In
pretty much every repo, we add a Constructor and within that add
the context (The context is how we query the DBsets/Domain models
via
Entity Framework). This is resolved by IOC (See below) so you
can get access to the database. Don't forget to add/update this or
you won't be able to query the data as no context will exist.
using System;
using System.Collections.Generic;
using System.Linq;
using MVCForum.Data.Context;
using MVCForum.Domain.DomainModel;
using MVCForum.Domain.Interfaces;
using MVCForum.Domain.Interfaces.Repositories;
namespace MVCForum.Data.Repositories
{
public class BannedWordRepository : IBannedWordRepository
{
private readonly MVCForumContext _context;
public BannedWordRepository(IMVCForumContext context)
{
_context = context as MVCForumContext;
}
public BannedWord Add(BannedWord bannedWord)
{
return _context.BannedWord.Add(bannedWord);
}
public void Delete(BannedWord bannedWord)
{
_context.BannedWord.Remove(bannedWord);
}
public IList<BannedWord> GetAll()
{
return _context.BannedWord.OrderByDescending(x => x.DateAdded).ToList();
}
public BannedWord Get(Guid id)
{
return _context.BannedWord.FirstOrDefault(x => x.Id == id);
}
public PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize)
{
var total = _context.BannedWord.Count();
var results = _context.BannedWord
.OrderBy(x => x.Word)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedList<BannedWord>(results, pageIndex, pageSize, total);
}
public PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize)
{
var total = _context.BannedWord.Count(x => x.Word.ToLower().Contains(search.ToLower()));
var results = _context.BannedWord
.Where(x => x.Word.ToLower().Contains(search.ToLower()))
.OrderBy(x => x.Word)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedList<BannedWord>(results, pageIndex, pageSize, total);
}
}
}
MVCForum.Data > MVCForum.Services
Now we add the service. And again as with the context in the
constructor of the Repo. This time, in the constructor of the class
we pull in the Repo we just created so we can get access to the
data.
The difference between the two classes is like this. The Repo
should be purely for getting data and returning it. The service is
for getting the data and then doing any complicated logic before it
passes it on (i.e. Remapping, filtering, sanitising content etc…).
So here is our Service.
using System;
using System.Linq;
using System.Collections.Generic;
using MVCForum.Domain.DomainModel;
using MVCForum.Domain.Interfaces.Repositories;
using MVCForum.Domain.Interfaces.Services;
using MVCForum.Utilities;
namespace MVCForum.Services
{
public class BannedWordService : IBannedWordService
{
private readonly IBannedWordRepository _bannedWordRepository;
public BannedWordService(IBannedWordRepository bannedWordRepository)
{
_bannedWordRepository = bannedWordRepository;
}
public BannedWord Add(BannedWord bannedWord)
{
return _bannedWordRepository.Add(bannedWord);
}
public void Delete(BannedWord bannedWord)
{
_bannedWordRepository.Delete(bannedWord);
}
public IList<BannedWord> GetAll()
{
return _bannedWordRepository.GetAll();
}
public BannedWord Get(Guid id)
{
return _bannedWordRepository.Get(id);
}
public PagedList<BannedWord> GetAllPaged(int pageIndex, int pageSize)
{
return _bannedWordRepository.GetAllPaged(pageIndex, pageSize);
}
public PagedList<BannedWord> GetAllPaged(string search, int pageIndex, int pageSize)
{
return _bannedWordRepository.GetAllPaged(search, pageIndex, pageSize);
}
public string SanitiseBannedWords(string content)
{
var bannedWords = GetAll();
if (bannedWords.Any())
{
return SanitiseBannedWords(content, bannedWords.Select(x => x.Word).ToList());
}
return content;
}
public string SanitiseBannedWords(string content, IList<string> words)
{
if (words != null && words.Any())
{
var censor = new CensorUtils(words);
return censor.CensorText(content);
}
return content;
}
}
}
You'll notice at the bottom there is a CensorUtils class. This
is something that is added in v1.3 to the forum. If you are
following this word for word, then just remove both
SanitiseBannedWords methods from the interface and implementation
as you won't need them for this tutorial.
Registering With The IOC Container
Once you have created both your Service and Repository you need
to register them in with the IOC container (We currently use
Unity for our IoC), or the repo in the service constructor
above won't work and you won't be able to use your service in the
controllers.
MVCForum.IOC > UnityMVC3.cs
This is a really simple couple of lines to add. Just open the
above file and add in the following for the service and repo.
container.BindInRequestScope<IBannedWordService, BannedWordService>();
container.BindInRequestScope<IBannedWordRepository, BannedWordRepository>();
It should be pretty self explanatory where to add these, the
services are all grouped together and so are the repos. All this
file does it point the interface to which implementation of the
interface to use. So you can swap out implementations top custom
ones if you want to.
Using The Service In A Controller
As you will see throughout and I mentioned above. The repo is
never used apart from by the services. They simply just
transfer/update/delete data from the database. But the services are
what you use and call from within the application.
So to get the data back and use what we have just created, we
need to call the service from your controller. This is very simple
and the same as how we called the Repo from within our service. We
just setup a constructor and initialise the service interface we
want to use and the IOC container will take care of the rest and
get the correct implementation.
For example. If I wanted to create a
BannedWordController then I would set it up like
this with the service in the constructor
using System.Web.Mvc;
using MVCForum.Domain.Interfaces.Services;
namespace MVCForum.Website.Controllers
{
public class BannedWordController : Controller
{
private readonly IBannedWordService _bannedWordService;
public BannedWordController(IBannedWordService bannedWordService)
{
_bannedWordService = bannedWordService;
}
public ActionResult Index()
{ // I can now use the service here by called
var getAllBannedWords = _bannedWordService.GetAll(); return View();
}
}
}
And that's it. We can call the service from any controller we
want as long as we set it up in the constructor like the above
example. [Less]
|