I have a service for creating, saving and sending different types of orders where some types of them will be able to carry attachements.
The service will send orders to another external service by using IExternalService which is used by several other services with different external endpoints.
IExternalService contains a getter for a external IRepository which is used to send orders to external services.
I've created a new interface for those repositories which will be adding attachements IRepositoryWithAttachement.
I'm providing some sample code below where i left out unimportant stuff:
interface IRepository //Standard repo used by different external services
{
string Create(Order order);
void Update(Order order);
}
Orders with attachements use
interface IRepositoryWithAttachement : IRepository //attachable repo
{
string AddFile(Attachement file);
void UpdateFile(Attachement file);
}
Repo that must send attachements aswell as orders
public class Repository : IRepositoryWithAttachement {...}
Service used by many implementations of external services
interface IExternalService
{
string Name { get; }
....
IRepository Repository { get; }
}
Main service class for creating, saving and sending orders
public class OrderService
{
public string Create(Order order)
{
...
IExternalService eService = _externalServices.GetExternalService(id);
try
{
eService.Repository.Create(order);
}
catch (Exception e)
{
....
}
...
}
Now this particular ordertype will be adding attachments and when it gets the repository with IExternalService it will get an IRepository back and trying to call eService.Repository.AddFile(file) but the AddFile method doesn't exist because the return type is IRepository which i want. But my IRepositoryWithAttachement is extending IRepository so i got confused how i would reach it and i managed to do this:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
try
{
((IRepositoryWithAttachement ) eService .Repository).AddFile(file);
}
catch (Exception e)
{
...
}
}
}
Question
Am i doing this wrong or is it an ugly solution to my problem of getting hold of the addfile method by typecasting?
The two biggest issues I see are that a) you seem to be using exception handling to protect against repositories that don't implement the interface you need, and b) you are catching Exception, rather than InvalidCastException and/or other specific exceptions which you can anticipate and handle correctly.
IMHO, a better implementation would look something like this:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
IRepositoryWithAttachement repository = eService.Repository as IRepositoryWithAttachement;
if (repository == null)
{
// report error in some appropriate way and return, or throw an
// _informative_ exception, e.g.
// new NotSupportedException("repository does not support attachments")
}
repository.AddFile(file);
}
Even better would be to categorize your available repository IDs and restrict access according to capabilities so that the AddFile() method is never called in the first place unless you know that the repository implements the necessary interface. Then you can safely cast without ever having to worry about an exception being thrown.
Unfortunately, without a good, minimal, complete code example to clearly illustrate the question, it would be hard or impossible to offer advice any more specific than the above with any assurance of relevance. It is entirely possible that there's a better approach available than what you're using now, but without more context it's not really possible to say what that would be.
Related
I have a legacy code, and I have a problem with reconstructor it.
At start of my application I load from WCF to property on App (this is SL application) list of users.
Then every control (for sending emails, view calendar and assigning tasks) use this property as
(App.Current as App).Users
Now, I'm trying to create Unit Test for one of controls that use this lists, and I'm stuck.
Should I make a Constructor Injection(I'm using Unity) with App as parameter? Or maybe introduce some class to hold this list?
Updated with OP's implementation as the pseudocode was incomplete.
I propose create an interface for all your application services
Inject IApplicationService to your modules.
You can use this interface for all the services the application provides(probably you will need more). Mock the interface for the unit tests
OP's implemantation
public interface IApplicationService
{
List<User> Users{get;set;}
}
public class ApplicationService : IApplicationService
{
public List<User> Users
{
get { return (App.Current as App).Users; }
set { (App.Current as App).Users = value; }
}
}
public partial class MainWindow : UserControl
{
readonly IApplicationService _applicationService
public MainWindow(IApplicationService applicationService)
{
_applicationService=applicationService;
}
}
I would create a wrapper class that will expose the list of users. In production code this class will just be a wrapper around your App.Current property and it can be injected in the constructor trough Unity.
In your Unit Tests you can easily mock the App parameter and pass it when constructing a new SUT.
Something like:
public interface IUserList
{
List<User> Users { get; }
}
public class SUT
{
private IUserList UserList { get; set; }
public SUT(IUserList userList)
{
this.UserList = userList;
}
}
public class AppUserList : IUserList
{
public List<User> Users
{
get
{
return ((App)App.Current).Users;
}
}
}
For Silverlight there is an extension model called Application Extension Services.
For infrastructure purposes that might be a better alternative than adding properties to your app class and casting App.Currentback and forth.
Downside of that model is the creation of a singleton you would have to initialize for your unit tests. It would also hide the dependency on Users in your consuming classes.
Your users seem to be just data. Making that data an ambient context which can be accessed and edited everywhere in your application will bite you. You don't know who does what with that data and when he does it. This is like a session state.
So making the dependency on your data explicit would be a first step to be able to track abuse of that data.
If it makes sense to you to create a "data holder object" that has a property for Users or directly inject that data into your consumers is up to you. If there is more data than just Usersit is tempting to put all of them into the same central data store object, even if your specific consumers don't need them.
Jimmy's answer is great, but can be provide quite a bit, and some errors fixed. Differences are explained at the bottom below the code/instructions:
Create a public interface: IUserService
public interface IUserService
{
// Implemented functionality as methods where possible for better
// extendability (like IoC)
IEnumerable<User> Users();
// Add any other user service stuff as you see fit.
void AddUser(User user);
}
Write a UserService that implements IUserService
public class UserService : IUserService
{
// If you need DI for this service, follow the same pattern of using
// fields and controller injection. I left examples in comment below.
// private readonly IRepository _repository;
// Constructor is unnecessary if you do not need DI example.
public UserService(/* IRepository repository */)
{
// _repository = repository;
}
// Methods
public IEnumerable<User> Users()
{
return ((App)App.Current).Users;
}
public void AddUser(User user)
{
((App)App.Current).Users.Add(user);
}
}
Inject IUserService into classes via their Constructor
In this case your MainWindow as an example:
public partial class MainWindow : UserControl
{
private readonly IUserService _userService;
public MainWindow(IUserService userService)
{
_userService = userService;
}
// Example method consuming the service
public IEnumerable<User> GetUsers()
{
return _userService.Users();
}
}
Differences:
Separate your User Services from a central Application Service
Better modularity. In addition I use an IApplicationService for more central/global data like Api Keys, Timeouts, cleanup, DB prepping, etc.
Return IEnumerable<T> instead of List<T>
This is just a golden rule of thumb for keeping things dry and not imposing hard instantiations on your consuming classes. Refactoring is easier/safer, and your code more extensible.
Use methods instead of properties
This is preference, but I think it smart in a service layer to use methods where possible so that you can introduce filters and overloads or continue to use dependency injection - for example, you could add GetUsers(string lastName), GetUsers(string lastName, string firstName) and maintain a clean interface for your consuming classes.
Cast App.Current without the as keyword
This is a good practice because using the as keyword means when the cast fails it will return null, rather than throw an exception. I prefer the exception because 99% of the time, if your cast fails, your next operations will too. :)
Enjoy!
I have been using the following pattern for my controller actions:
public ActionResult Create(CreateViewModel model) {
if( !ModelState.IsValid ) {
return View(model);
}
var project = new Project {
Name = model.Name,
// ...
};
projectRepository.Add(project);
return RedirectToAction("Index");
}
This works for simple scenarios, but I have had a few situations where a repository is not enough. I created a service layer / class that will handle saving the project and any extra business logic (not normal validations with fluent validation or data annotations).
public class ProjectService : IProjectService {
void AddProject(Project project) {
// do business logic
// ...
repository.Add(project);
}
}
How can my service layer easily communicate with my controller?
These are the types of things I would like to communicate to the controller:
Business Logic / Validation errors
Database Failures (failed to save etc.)
How can I do this without just returning true/false or status codes from the service layer?
Be careful if you choose exceptions, these are expensive. It gives your controller code extra nesting too, depending on how many exceptions may be thrown. You should really only throw an exception for an exceptional condition, not something that should be handled by the normal flow of your application.
I would go with the other route Wouter de Kort suggested, use the return type of the service for a messaging object. You can key a return message object on a simple enum with the various cases the service may encounter. These look better in the controller because you can handle the enum with a switch/case rather than a try/catch.
Update
What a messaging object may look like:
public interface IServiceAbc
{
ServiceResponse InvokeMyService([params]);
}
public enum ResponseScenario
{
Success,
DatabaseFailed,
BusinessRuleViolated,
ValidationRuleViolated
}
public class ServiceResponse
{
public ResponseScenario Scenario { get; internal set; }
public string Message { get; internal set; }
}
If you want to return detailed messages when an error occurs you could always use Exceptions. Maybe define your own with specific details or reuse the ones that are already in the .NET Framework.
If that´s not an option you could always return a wrapper class which could contain more detailed error information and handle that in the Controller.
I have a service that reads all emails as they get received in a specific mailbox. The issue is that based on what the email contains we have to do one or many actions. I currently have the mess below. I've shortened it quite a bit. The actual application currently has far more corner cases.
var email = new Email { Body = "Some random email body text..." };
if(email.Body.StartsWith("A"))
{
// Requires a dependency on INotifier
Console.WriteLine("Notifying administrator");
}
if (email.Body.StartsWith("B"))
{
// Requires a dependency on IParser and IRepository
Console.WriteLine("Parsing email and adding to database");
}
if (email.Body.EndsWith("C"))
{
// Requires a dependency on ISender and INotifier
Console.WriteLine("Forwarding email and notifying administrator");
}
if (email.Body.EndsWith("C"))
{
// Requires a dependency on INotifier
Console.WriteLine("Ignoring email");
}
Essentially, if a criteria is met then an associating action must get executed using one or more dependencies. These dependencies are something I'd like to inject in the constructor.
I've thought of creating something like this:
public class AdministratorNotififerCriteria : ICriteria
{
private readonly INotifier _notifier;
public AdministratorNotififerCriteria(INotifier notifier)
{
_notifier = notifier;
}
private void Execute()
{
_notifier.Notify();
}
public void CheckSatisfaction(Email email)
{
if(email.Body.StartsWith("A"))
Execute();
}
}
The bottom line is that I wish to make composable commands. So when I add another criteria down the line then all I have to do is inherit from ICriteria (or whatever) and let the application figure it out.
Is there a name for all of this?
I currently have a consumer that resembles this.
public class EmailConsumer
{
private readonly IEnumerable<ICriteria> _criterias;
// Criterias are found and injected with Windsor from all classes inheriting the ICriteria interface
public EmailConsumer(IList<ICriteria> criterias)
{
_criterias = criterias;
}
public void Consume(IList<Email> emails)
{
foreach(var criteria in _criterias)
{
foreach(var email in emails)
{
criteria.CheckSatisfaction(email);
}
}
}
}
Edit
Thanks for the replies, IAbstract and djna. I now understand what the strategy and CoR pattern do and thinking about which is more appropriate is proving that I don't understand enough of my current problem.
The way I understand it is that CoR is greedy and whoever can take responsibility will execute and proceed to the next object to be consumed. On the other hand, there doesn't seem to be anything stopping from looping between strategies that says "Hey! I can consume this request properly so don't worry about it".
This seems like a variation of Chain of responsibility with possibly some extra logic for dealing with non-exclusive cases - what do you intend should happen if the Body starts with "A" and ends with "C"?
One idea in Chain of Resposibility is that there's no need for a huge dispatching if/else chain. Instead you just offer the email to some ICriteria implementatio, and they have responsibility either to process or pass on to the next candidate.
#djna suggests a variation of the CoR pattern. I don't completely disagree. It seems more like this example of the Strategy Pattern.
In previous question folks helped me to solve repository lifetime problem, now there's a question how to make it work nicely in composite service.
let's say i have services:
public class OrderService : IOrderService
{
IRepository<Order> orderRepository;
public OrderService(IRepositoryFactory repositoryFactory)
{
orderRepository = repositoryFactory.GetRepository<Order>();
}
public void CreateOrder(OrderData orderData)
{
...
orderRepository.SubmitChanges();
}
}
public class ReservationService : IReservationService
{
IRepository<Reservation> reservationRepository;
public ReservationService(IRepositoryFactory repositoryFactory)
{
reservationRepository = repositoryFactory.GetRepository<Reservation>();
}
public void MakeReservations(OrderData orderData)
{
...
reservationService.SubmitChanges();
}
}
And now the intersting part - composition service:
public class CompositionService : ICompositionService {
IOrderService orderService;
IReservationService reservationService;
public CompositionService(IOrderService orderService, IReservationService reservationService)
{
this.orderService = orderService;
this.reservationService = reservationService;
}
public void CreateOrderAndMakeReservations(OrderData orderData)
{
using (var ts = new TransactionScope())
{
orderService.CreateOrder(orderData);
reservationService.MakeReservations(orderData);
ts.Complete();
}
}
}
Problem is, that it won't work correctly if IRepositoryFactory lifestyle is transient (because you would get two different datacontexts and that would require distributed transactions to be enabled, which we try to avoid). Any ides how to write this correctly?
My observations:
In general, factories should be singletons. If your factory isn't a singleton, then you are probably just hiding another factory behind it.
Factories are meant for creating objects on demand. Your code simply creates a repository in the constructor, so I don't really see the difference between that and simply making the repository a direct injection parameter in the constructor.
These all seem to me like a workarounds around a more fundamental problem (described in your first question) and these workarounds only make the problem more complicated. Unless you solve the root problem you will end up with a complex dependency schema and a smelly code.
IMO - this is a Distributed Transaction scenario.
In the example you mentioned, OrderService & ReservationService use the same data context is an implementation detail hidden in the code.
I don't think it is correct to pass this knowledge up to the CompositionService by wrapping the service calls in a TransactionScope as now the composition service is aware of the shared data context & so needs to use a TransactionScope to run the code correctly.
In my opinion, the composition service code should look like:
try{
if(orderService.TryCreateOrder(orderData)){
if(reservationService.TryMakeReservation(orderData)){
reservationService.Commit();
orderService.Commit();
}
else{
orderService.TryRollbackOrder(orderData);
throw new ReservationCouldNotBeMadeException();
}
}
else{
throw new OrderCouldNotBeCreatedException();
}
}
catch(CouldNotRollbackOrderServiceException){
// do something here...
}
catch(CouldNotCommitServiceException){
// do something here...
}
In this case, the OrderService.TryCreateOrder method will insert an Order with a PendingReservation status or some other relevant status which indicates that the Order is inserted, but not completed. This state will change on the commits are called on the services (UnitOfWork pattern?)
In this case, the implementation details of the services are completely hidden from the consumer of the service, while composition is also possible, independent on the underlying implementation detail.
HTH.
I am trying to avoid the conventional:
if(!user.HasPermission(Actions.UpdateRecord))
{
// code to update record
}
on a large number of permissions all over my application.
I am looking for a means of checking for permissions in an effective and (if possible) elegant manner.
In this case there are multiple actions within each permission.
How about putting a decorator on your dataaccess objects. The decorator pattern is very useful for doing things like handling permissions. Your dataAccess layer can do just data access and then your decorate those classes with something that handles permissions and permissions only.
It is very elegant...
http://en.wikipedia.org/wiki/Decorator_pattern
There are a lot of ways to do this. The important thing is that you want to encapsulate the concern of checking permissions. One way to do this is with a strategy pattern. Encapsulate the action in a class, and get the class via a factory method. The factory can do the security check, and return a different strategy for disallowed actions.
For example:
public abstract class SecureAction
{
public void PerformAction();
}
public class UpdateRecords : SecureAction
{
public void PerformAction()
{
//code to do the update
}
}
public class DoesNotHavePermissionAction : SecureAction
{
public void PerformAction()
{
//code to handle missing permissions
}
}
public class SecureActionFactory
{
public void GetUpdateRecordsAction(User user)
{
if(user.HasPermissions(Actions.UpdateRecord)) {return new UpdateRecordsAction();}
return new DoesNotHavePermissionAction();
}
}