I am new to design patterns and now I want to implement the Strategy patern. Here's my code:
namespace StrategyPattern
{
public interface ISendBehavior
{
void Send();
}
public class SendAppointment : ISendBehavior
{
public void Send()
{
// send item
}
}
public class SendTask : ISendBehavior
{
public void Send()
{
// send item
}
}
public class SendItem
{
ISendBehavior _sendBehavior;
public SendItem(ISendBehavior sendbehavior)
{
_sendBehavior = sendbehavior;
}
public void Send()
{
_sendBehavior.Send();
}
}
/* CALL */
public class Aanroep
{
public void Verzenden()
{
SendItem app = new SendItem(new SendAppointment());
app.Send();
}
}
}
In the method Send in the class SendAppointment the item will be send. My question is, do I have to connect to the database in this class? If so, then I also have to connect to the database in SendTask. But at this point I am repeating myself right? So if a connection string changes, i have to modify this in every class. How can I solve this problem?
You could have another layer of abstraction for the database operations. This layer should be responsible for taking all the database requests centralizing the access. Connections strings should be configured externally, and the data mapping layer could access them directly.
The Repository Pattern is a good pattern for this layer that you can apply. It can sit between your domain objects and the data mapping layers.
How about initializing each implementor of ISendBehavior with yet another object that's responsible for the database connection?
Your Verzenden()-implementation would be something like
IDatabaseConnection connection = new DatabaseConnection();
SendItem app = new SendItem( new SendAppointment( connection ) );
and your ISendBehavior.Send() would be implemented like this
_databaseConnection.Send( ... ); // fill behavior-specific information here (perhaps with properties)
This way, you can reuse that IDatabaseConnection for any other classes.
Since you don't like Lennaert answer of passing the connection to your class why not reverse it and create a connection class that uses a simple command pattern and pass your class to it as a the parameter?
Related
ASP.NET MVC 5 Project.
I know that the best practice of using EF context object as the following
using(var context = new ContextDB())
{
}
But I am working with a large existing project which not used this practice.
the project using the following pattern
public abstract class BaseService
{
private static ContextDB _data { get; set; }
public static ContextDB Data
{
get
{
if (_data== null)
_data= new ContextDB();
return _data;
}
}
}
Actually, because of this pattern, I am receiving this exception (sometimes, not always)
So to solve this I have to change all the code which is using the shared Data
property and replace it with the new instance of ContextDB as I mentioned in the beginning of the question.
The problem that this is a very large modification, and I will not be allowed to do that modification.
The Question, can I solve this problem without changing a ton of code, In another word, can I solve the problems with modifications done only inside the BaseService class, for example, Is there any event which I could handle to know if any query is executed and then dispose of the ContextDB
here is the pseudo-code of the idea in my mind
public abstract class BaseService
{
public static ContextDB Data
{
get
{
ContextDB _data= new ContextDB();
_data.SqlQueryExecuted += () => { this._data.dispose(); }
return _data;
}
}
}
NOTE: the SaveChanged event is not suitable, because not all of the query are updating or inserting.
I may use following solution.
In Global.asax
Begin Request : Create Instance of your dbContext. Store it in HttpContext.Current.Items.
End Request : Grab the context and close / dispose connection.
Another better solution is to use DI. Dependency Injection and limit the scope of your instance. There are many way Like Singleton, PerRequest etc.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am a young developer who starts, I'm just learning Dependency injection and i have a question that torments me.
In my exemple I have a WCF service web (soap), it performs some simple business action and makes a call to the database.
So , my project is cut into
Service -> Business Layer -> Layer Data Access -> Data base
in my case, there is simple business action in business layer and à SELECT statment in data access layer .
So now (certainly wrong way) I used static class to communicate between my layers:
In summary :
Service Layer:
public void GetData()
{
BusinessLayer.GetData();
}
Business layer :
static class BusinessLayer
{
public static void GetData()
{
//If something or something else ...
DataAccessLayer.GetData();
}
}
Data Access Layer:
static class DataAccessLayer
{
public static void GetData()
{
//DO insert in database
}
}
First, is this a bad way to go?
Then, for this kind of very simple case, is that it is worthwhile to set up an IoC container?
Thank you in advance .
PS: Sorry for my English
I would make interfaces out of your layer classes. This removes the static classes, as desiried, and sets you up for injection. For your example, which is rather small, I would not recommend going through the trouble unless as a learning experience. There are no hard rules for when to use this injection but the pattern helps tremendously when unit testing comes about.
Nobody ever said: "Wow! This would have been much easier to write a unit test for if it were a static method or singleton!"
In the end you will have something along the lines of interface for the functionality you want to inject. This assumes some level of domain model will exist and raw data from the database will be converted into the model.
You would begin by defining the various interface you have to have injected into you dependent classes.
public interface IBusinessLayer
{
Data GetData();
}
public interface IDataAccessLayer
{
Data GetData();
}
public interface IDatabase
{
DbData GetDatabaseData();
}
The main goal is to have the container inject the funcitonality you to complete the operations desiried. In this, getting data. Assuming you data is a class in the domain model.
public class ServiceLayer
{
IBusinessLayer business = null;
public ServiceLayer(IBusinessLayer business)
{
this.business = business;
}
public void GetData()
{
Data data = business.GetData();
// do something with data
}
}
You can repeat the same pattern for the different layers. While this seems a lot of work for a simple application the hard edged given by the interfaces allow each layer to evolve on it own ... so long as the interface contract remains.
The segregation is nice if you keep the layers clearly defined. For example, by not letting raw database data, rows etc. bleed up into the upper layers.
public class BusinessLayer : IBusinessLayer
{
IDataAccessLayer dataAccess = null;
// container will inject data access layer
public BusinessLayer(IDataAccessLayer dataAccess)
{
this.dataAccess = dataAccess;
}
public Data GetData()
{
Data data = dataAccess.GetData();
// do something with data?
return data;
}
}
// Retruns typed data business layer
public class DataAccessLayer : IDataAccessLayer
{
IDatabase db = null;
public DataAccessLayer(IDatabase db)
{
this.db = db;
}
public Data GetData()
{
var db_data = db.GetDatabaseData();
Data data = /*convert raw db_data -> type domain data*/
return data;
}
}
I have created a generic repository for my entity types which handles retrieving , adding and deleting data. Each entity type has a corresponding Service class which interacts with the generic repository to handle all the Data access.
However many times i need to retrieve data based on more than one service and i am never sure where to place this code. For example below is some code that returns a list of email addresses ("GetEmailTrackingAddressGroup" function) which is using 3 different service. I have placed this in the "GroupService" but it could also easily go in the "UserService" aswell.
public class GroupService
{
IRepository<Group> groupRepository;
public GroupService(IRepository<Group> groupRepository)
{
this.groupRepository = groupRepository;
}
public Group GetById(int id)
{
return groupRepository.GetSingle(g => g.Id == id);
}
public static List<string> GetEmailTrackingAddressesGroup(int instanceId, int groupId)
{
MyEntities entityContext = new MyEntities();
UserGroupService userGroupService =
new UserGroupService(new BaseRepoistory<UserGroup>(entityContext ));
UserService userService =
new UserService(new BaseRepoistory<User>(entityContext ));
List<string> emails = new List<string>();
Group productGroup = GetById(groupId);
foreach (UserGroup userGroup in userGroupService.GetByGroupId(productGroup.Id))
{
if (userGroup.EmailTracking)
emails.Add(userService.GetByUserId(userGroup.UserId).UserName);
}
return emails;
}
}
My Question is, should you just try and pick the most relevant service and place the code in there and call the other relevant service inside it, or should i create a new class which handles Data access when more than 1 service is involved. For example i have placed code for what this class might look like below.
public class DataFunctions
{
public static List<string> GetEmailTrackingAddressesGroup(int instanceId, int groupId)
{
MyEntities entityContext = new MyEntities();
GroupService userGroupService =
new GroupService(new BaseRepoistory<Group>(entityContext ));
UserGroupService userGroupService =
new UserGroupService(new BaseRepoistory<UserGroup>(entityContext ));
UserService userService =
new UserService(new BaseRepoistory<User>(entityContext ));
List<string> emails = new List<string>();
Group productGroup = GetById(groupId);
foreach (UserGroup userGroup in userGroupService.GetByGroupId(productGroup.Id))
{
if (userGroup.EmailTracking)
emails.Add(userService.GetByUserId(userGroup.UserId).UserName);
}
return emails;
}
}
The second approach seems to make more sense as this means each service will never rely on other services however im not sure if i am going about this the right way. One concern i have about using this separate class is that it will get very big and hard to manage.
Edit - For now i have come up with a third solution, i think it is better than my previous two however i'm still uncertain if i am managing this correctly. I have created a seperate "EmailService" which will handle all data queries which are needed when handing email functionality in my main ASP.Net web project.
Below is the code for this new class
//Functionality realting to data needed when handling emails
public class EmailService
{
MyEntities entityContext;
AspUserService aspUserService;
GroupService groupService;
UserGroupService userGroupService;
public EmailService()
{
entityContext = new MyEntities ();
aspUserService = new AspUserService(new RepositoryBase<aspnet_Users>(entityContext));
groupService = new GroupService(new RepositoryBase<Group>(entityContext));
userGroupService = new UserGroupService(new RepositoryBase<UserGroup>(entityContext));
}
public List<string> GetEmailsForProductGroup(int groupId)
{
List<string> emails = new List<string>();
Group productGroup = groupService.GetById(groupId);
foreach (UserGroup userGroup in userGroupService.GetByGroupId(productGroup.Id))
{
if (userGroup.EmailTracking)
emails.Add(aspUserService.GetByUserId(userGroup.UserId).UserName);
}
return emails;
}
}
If you were to do maintenance on an application you've never seen before, where would you expect it to be? Since it is something that "belongs" to a group, i think that putting it in the group-repo/service would be the right approach. In your example, i would suggest creating a new group-repository, extending the IRepository of group, and create a method for getting the group object, including the connection entities. When scaling your application, this will make a huge difference, since you wont have to query the database for every subobject (n+1 problem).
No offense, but all your approaches suck for the following reasons: tight coupling and messing around responsibilities.
The generic repository is an anti pattern, stay away from it. Your first approach pretty much does the work of a repository and it's a static function (why?!).
The services shouldn't be coupled to concrete repositories. All dependencies should be injected as abstractions via constructor. I get the feeling that aspUsersService,GroupService and UserGroupService (what's the difference????) are actually implemented like a repository and thus, they are useless.
Actually from what I see, all your services are practically repositories. Cut the useless code, have one service/repository that uses directly EF and that's it.
It looks like you're a little confused between the point of repositories and service classes. Your service classes are just repositories. You ended up having to work this way because of the generic repository pattern. This pattern is actually an anti-pattern. It seems nice at first until you get to the point you're at. Instead you should create repositories for each of your entities that handle all CRUD operations for that entity. In these repositories is where you'll place your 'GetEmailTrackingAddressesGroup' type methods. And then your service layer can handle interacting with more that one repository if need be. Your service classes shouldn't have hard coded instances of your repositories. Instead you should be inject repository interfaces into your service's constructor.
Here's an example of how I would set up repositories and a simple service that interacts with 2 repositories.
public interface IUserRepository
{
void Insert(User user);
...
IEnumerable<User> GetByDepartmentId(int deptId);
}
public interface IContactLogRepository
{
void Insert(ContactLog contactLog);
}
public class EmailService
{
private readonly IUserRepository _userRepo;
private readonly IContactLogRepository _contactLogRepo;
public EmailService(IUserRepository userRepo, IContactLogRepository contLogRepo) {
_userRepo = userRepo;
_contactLogRepo = contLogRepo;
}
public void EmailDepartment(int deptId, string message) {
var employees = _userRepo.GetByDepartmentId(deptId);
foreach (var emp in employees) {
Email(emp.Email, message);
_contactLogRepo.Insert(new ContactLog {
EmployeeId = emp.Id,
Message = message
});
}
}
private void Email(string address, string message) {
...
}
}
So our repositories are there to handle CRUD operations for a specific entity - not our service layer. The generic repository pattern forces us to do CRUD (well at least the retrieval) in our services.
I'm creating a class library API that wraps business logic and access to an SQL Server database via Entity Framework 6.
I've designed it using the Unit of work and repository patterns.
The purpose is to make it easy to use and to unit test.
Business logic and validation will be performed in the service layer.
I will not use an IOC container because I feel that it would complicate the API
usage.
The project have 15 repositories and services
The current design is as follows:
Service Layer A -> Unit of work -> Repository A and or B
Service Layer B -> Unit of work -> Repository B and or A...
...
public class ServiceA : IServiceA, IService
{
private readonly IUnitOfWork unitOfWork;
public AssetService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
...
public IList<DomainObjectA> GetAll()
{
return unitOfWork.RepositoryA.GetAll();
}
public void Dispose()
{
unitOfWork.Dispose();
}
...
}
public class UnitOfWork : IUnitOfWork
{
private readonly MyDbContext context = new MyDbContext();
private IRepositoryA repositoryA;
private IRepositoryB repositoryB;
...
public IRepositoryA RepositoryA
{
get { return repositoryA = repositoryA ?? new RepositoryA(context); }
}
public IRepositoryB RepositoryB
{
get { return repositoryB = repositoryB ?? new RepositoryB(context); }
}
...
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public class RepositoryA : Repository, IRepositoryA
{
public RepositoryA(MyDbContext context)
: base(context) {}
public IList<DomainObjectA> GetAll()
{
return context.tblA.ToList().Select(x => x.ToDomainObject()).ToList();
}
...
}
Since this is an API that should be used by other projects, I need a nice and "fairly" easy to use interface for the user that consumes the API.
Because of this the UnitOfWork is created in this "public interface" between the user and the service layer, see below.
I also think it's best that the using-statement lies within the API so that the db-context is disposed properly and immediately after each service call.
I started out using the Proxy pattern for this:
Example:
public class ProxyA : Proxy, IServiceA
{
public IList<DomainObjectA> GetAll()
{
using (var service = GetService<ServiceA>())
return service.GetAll();
}
...
}
public abstract class Proxy
{
protected T GetService<T>() where T : IService
{
return (T)Activator.CreateInstance(typeof(T), new object[] { new UnitOfWork()});
}
}
But this would require me to create a proxy for each service. I could of course skip the service interface in the proxy and create a common proxy which handles all the services.
I've also looked at the Facade pattern but can't decide which pattern to use for this particular scenario.
My questions:
Is this a good approach or are there any other design patterns that will solve this problem?
Also, should there be one public API entry point or several, grouped by some business logic?
I see nothing wrong with your design and the patterns you use.
Regarding the proxy pattern it is your call if you want to use it or not. As you mention you have to create boiler plate code to create one for every service. If it is arguable if you want to use it only to hide the call to the db service, or you prefer to add that line of code every time you call the service (and make sure you do it to avoid leaks). Also you may consider if you may need to add extra functionality in the Proxy in the future, which will put extra weight to create the proxy option.
Regarding a single entry point or several, I would create a ServiceA, ServiceB, ServiceC etc (so several) grouped for business logic domains. Typically you'll have between 5-20 (just an approximate number to give an idea of the magnitude)
You may want to review the interface segregation principle which supports this idea
http://en.wikipedia.org/wiki/Interface_segregation_principle
I have a occasionally connected application where there is a server that stores information about products. I am using a database cache to store this information locally so when a connection is unavailable the application will still work when trying to read the database.
Since the database is configured and I do not have access to modify the tables, I did not implement 2 way updating and it only downloads a snapshot. A side question is if it is possible to create a database cache and have 2-way sync with only tracking columns on the client machine? I cannot add any columns or tables to the server. I know this might be a question for a separate post, but if this is true then it would change my direction for this problem completely, to a separate module detecting and syncing the database and handling any sync errors that are thrown and always connecting to the cache.
I am using a generic repository and I am wondering what the best practice to go about handling if a connection is available or not and using either a local or remote database depending on this status.
Should I add an interface to the generic repository that handles returning the correct string, and lets the repository know if it is live or not? I need to enable/disable certain features depending on the connection state so I also will need a property somewhere so that when this repository is used there can be a way to bind various controls enabled state to this status.
Instead should I have a wrapper that contains for example an IRepository and IConnectionStringManager and then handles feeding and initializing the repository connection string based on availability? This wrapper would expose the repository and any status properties required.
I guess I am not sure if I should be setting up my program to use IRepository with all the automatic connection sensing behind the scenes, or if I should have IRepositoryManager that has a IRepository and IConnectionStringManager in it.
Maybe both of those options are wrong?
I like the way Entity Framework allows you to provide a connection string as a constructor argument to its contexts. That way you can leverage a dependency injection framework to apply special logic when creating the context, and you only have to change the code in one place (assuming you're using DI principles). You could do something similar with your repository implementation.
Update
Since you're using Entity Framework, here's an idea of what it might look like in code:
// DI Bindings, Ninject style
Bind<Func<MyContext>>().ToMethod(
c => new MyContext(
c.Kernel.Get<IConnectionManager>().IsOnline()
? OnlineConnectionString
: OfflineConnectionString));
// Usage
public class ThingRepository : IThingRepository
{
private Func<MyContext> _getContext;
public ThingRepository(Func<MyContext> getContext)
{
_getContext = getContext;
}
public IEnumerable<Thing> GetAllThings()
{
using(var context = _getContext())
{
return context.Things.ToList();
}
}
}
Or, if you prefer to use a more explicit factory implementation:
public interface IMyContextFactory
{
MyContextFactory Get();
}
public class MyContextFactory : IMyContextFactory
{
private const string OnlineConnectionString = "...";
private const string OfflineConnectionString = "...";
private IConnectionManager _connectionManager;
public MyContextFactory(IConnectionManager connectionManager)
{
_connectionManager = connectionManager;
}
public MyContextFactory Get()
{
var connectionString = _connectionManager.IsOnline()
? OnlineConnectionString
: OfflineConnectionString
return new MyContext(connectionString);
}
}
// DI Bindings, Ninject style
Bind<IMyContextFactory>().To<MyContextFactory>();
// Usage
public class ThingRepository : IThingRepository
{
private IMyContextFactory _myContextFactory;
public ThingRepository(IMyContextFactory myContextFactory)
{
_myContextFactory = myContextFactory;
}
public IEnumerable<Thing> GetAllThings()
{
using(var context = _myContextFactory.Get())
{
return context.Things.ToList();
}
}
}