I need presentation layer in silverlight, asp.net etc , so everything is through wcf services.
I have number of doubts in my implementation of repository layer, service layer, wcf services
things i currently do
I have repository , its not per table its created per aggregate root
I have service layer its for doing a group of actions involving multiple repository
WCF service wraps the methods in service layer and repository layer
The entities are auto generated by EF
The entities are passed and returned to service layer as complete graph
6.I have two concrete class with all repository , and service called repositorycontainer and service container , Repository container is passed to the service
My repository base
public class RepositoryBase
{
public DataBaseContext _Context;
public RepositoryContainer _RepositoryContainer;
public RepositoryBase(RepositoryContainer repositoryContainer)
{
_RepositoryContainer = repositoryContainer;
_Context = repositoryContainer.Context;
}
public RepositoryBase()
{
_RepositoryContainer = new RepositoryContainer();
_Context = _RepositoryContainer.Context;
}
}
My repository container
public class RepositoryContainer
{
public RepositoryContainer()
{
Context = new DataBaseContext();
}
public RepositoryContainer(DataBaseContext context)
{
Context = context;
}
public DataBaseContext Context
{
get;
set;
}
public SurveyRepository _SurveyRepository;
public SurveyRepository SurveyRepository
{
get
{
return _SurveyRepository ?? (_SurveyRepository = new SurveyRepository(this));
}
}
}
My service container
public class ServiceContainer
{
public ServiceContainer()
{
RepositoryContainer = new RepositoryContainer();
}
public ServiceContainer(RepositoryContainer container)
{
RepositoryContainer = container;
}
public RepositoryContainer RepositoryContainer
{
get;
set;
}
public SurveyService _SurveyService;
public SurveyService SurveyService
{
get
{
return _SurveyService?? (_SurveyService= new SurveyService(this));
}
}
}
To do an operation
I just create RepositoryContainer or ServiceContainer
then calls
RepositoryContainer.Repository.Method()
ServiceContainer.Service.Method()
My doubts are
Is that service / respository container fine ?
I already have the service layer, so as i have wcf service what i call the current service layer servicewrapper or something ?
I need to call repository methods itself eg: GetCategory() etc , also all methods in service layer, So i need to wrap both methods and service in wcf service, is it fine ?
Where to do the caching ? as i am using EF i think there is something way to use a cache provider with EF ,
Is that service / respository
container fine ?
The RepositoryContainer class contains a "SurveyRepository" - but shouldn't the SurveyRepository be an instance of a RepositoryContainer? Same for ServiceContainer and "SurveyService". It would make more sense to me if they were (although it's hard to comment accurately without being more familiar with the project).
You'd then have: ServiceContainer SurveyService = new ServiceContainer(..);
As you have it, I get the impression that "SurveyService" is a specific business concept but it's wrapped up in a more generic type (ServiceContainer); same for SurveyRepository / RepositoryContainer.
This will break SRP, Common Closure Principle and probably Common Reuse Principle.
I'm not sure what other think, but I'm also not a fan of naming instances after their types (except in the most basic of senarios - which this isn't): public SurveyRepository SurveyRepository The name of the type should reflect what the type is (or does) which will be quiote different from a specific instance of it (like ServerContainer and ServeyService).
I already have the service layer, so
as i have wcf service what i call the
current service layer servicewrapper
or something ?
and
So i need to change name of my service
(BL) layer to something service
wrapper or something , then in wcf
service layer i define methods in
repository and service then just calls
curresponding methods in service,
repository
Generally any reusable BL should be in a standalone package and not enclosed (think "hard-coded") in a service layer or WCF service, etc. You'd then create service end-points that sat on top of the BL. If you have business transactions that span different business objects within different packages then you'll need to put that higher level orchestration somewhere higher - I guess this could go in the service layer, but this isn't a trival thing to do, you'll need to carefully consider where certain responsibilities lie.
If the transaction scover different business objects within the same package then the orchestration is much simpler and can be done with another BL type designed to handle that job, which will be part of that package - and not in the service layer.
Regarding the naming - go to a whiteboard and map everything out, and then rename everything as required. At least with a single cohesive overview you'll be able to make clear sense of everything.
BL packages should be named as appropriate to what they do - in business terms. WCF services that wrap these should have a name that fits and this could include reference to the type of channel being used (JSON, WebService, etc). Because you can change the channel a WCF service uses by config (if the service is design correctly) this might not be a good idea - but assuming it doesn't then the extra clarity might be helpful.
These articles might be of help:
http://blogs.oracle.com/christomkins/2009/07/my_thoughts_on_service_naming.html
http://ea.typepad.com/enterprise_abstraction/2006/08/service_naming_.html
What naming convention do you use for the service layer in a Spring MVC application?
I need to call repository methods
itself eg: GetCategory() etc , also
all methods in service layer, So i
need to wrap both methods and service
in wcf service, is it fine ?
Wrapping a service in a service sounds a bit suspect. Only external callers should go through the services - assuming the services are designed to expose the BL to external parties. Internal callers should know which is the appropriate method to call (by virtue of being internal), presumably it's the same method that is exposed by the service.
Where to do the caching ? as i am
using EF i think there is something
way to use a cache provider with EF
I don't know if you can cache in EF4 but it wouldn't surprise me if you can. Where to do caching? - it depends on where the bottle kneck is that you're trying to eliminate.
In your RepositoryContainer, the _SurveyRepository field is public - shouldn't it be private? Otherwise why have a read-only (get) SurveyService property?
public SurveyRepository _SurveyRepository;
Related
I'm building an application that performs actions initiated by a user and one particular class has dependencies on things I can wire up in DI such as an ILogger instance as well as an HttpClient in addition to runtime arguments that identify the user and the instance of the action (mostly to be used while logging to help with debugging).
The trouble I have is that I'm not entirely sure how to inject this class into the other classes that need it as a result of the runtime dependencies.
Here's a simplified example of one of my classes:
public class Dependency : IDependency
{
private readonly HttpClient httpClient;
private readonly ILogger<Dependency> logger;
private readonly RuntimeDeps runtimeDeps
public Dependency(
ILogger<Dependency> logger,
HttpClient httpClient,
RuntimeDeps runtimeDeps)
{
// set private fields
}
public Result DoStuff()
{
// use Http client to talk to external API
// something fails so log the failure and some helpful info
logger.log($"{runtimeDeps.InstanceId} failed. " +
"Initiated by {runtimeDeps.UserName}");
}
}
This feels like it requires a factory to create but then is it best to request the HttpClient and Logger in the factory method or declare it as a dependency of the factory? If the latter, I presume the factory would have to be registered as a transient or as a scoped resource since registering it as a singleton would result in a captive dependency (I think).
Any suggestions on redesigns are also welcome if this is a symptom of a poor design. I'd love to implement Mark Seeman's Pure DI to get some more assistance from the compiler but I don't know if that's possible in Azure functions.
A transient factory with the transient dependencies injected into the constructor and the runtime dependencies as parameters of the Create method will work fine.
DI is baked into the Azure Functions library in the sense that parameters are injected into the trigger methods, but beyond these you should be able to use Pure DI to manage your own dependencies by calling into some composition root helper class from the trigger function which knows how to build your dependency graph in a pure manner.
Instead of requiring runtime data during the construction of a component, it's better to let runtime data flow through method calls on an initialized object graph by either:
passing runtime data through method calls of the API or
retrieving runtime data from specific abstractions that allow resolving runtime data.
I formalized this in 2015 in this blog post, which I referred to in the comments.
After reading your additional comments, I came to the conclusion that in your case option 2 is most suited, as the data you are sending is likely an implementation detail to the component, and should not be part of the public API.
In that case, you can redesign your component as follows:
public class Dependency : IDependency
{
public Dependency(
ILogger<Dependency> logger,
HttpClient httpClient,
IRuntimeDepsProvider provider) ...
public Result DoStuff()
{
// use Http client to talk to external API
// something fails so log the failure and some helpful info
logger.log($"{provider.InstanceId} failed. " +
$"Initiated by {provider.UserName}");
}
}
IRuntimeDepsProvider is an abstraction that hides the retrieval and storage of runtime data. This gives you the ability to postpone the decision to either use a Closure Composition Model or an Ambient Composition Model until the Last Responsible Moment.
Using the IRuntimeDepsProvider abstraction, you can chose to set the incoming runtime values after the object graph is constructed. For instance:
public class MyFunction
{
// Notice the different abstraction here
public MyFunction(
IRuntimeDepsInitializer initializer,
IHandler<Something> handler) ...
public void TheFunction(Guid instanceId, string userName, Something cmd)
{
// Setting the runtime data *after* the object graph is constructed,
initializer.SetData(instanceId, userName);
// but before the graph's public methods are invoked.
handler.Handle(cmd);
}
}
Here, a second abstraction is introduced, namely IRuntimeDepsInitializer. Now you can have one class implementing both interfaces:
public class RuntimeDepsStorage : IRuntimeDepsInitializer, IRuntimeDepsProvider
{
public Guid InstanceId { get; private set; }
public string UserName { get; private set; }
public void SetData(Guid id, string name)
{
InstanceId = id;
UserName = name;
}
}
TIP: Instead of using two interfaces, you can also use only IRuntimeDepsProvider and let MyFunction depend on the concrete RuntimeDepsStorage. Which solution is best depends on the context.
Now the main trick here is to make sure that RuntimeDepsStorage becomes a Scoped dependency, because you want to reuse it throughout a request, but not shared by multiple requests.
When applying Pure DI, this would look like this:
var storage = new RuntimeDepsStorage();
new MyFuncion(
initializer: storage,
handler: new SomethingHandler(
stuffDoer: new Dependency(
httpClient: client, // Did you notice this is a runtime dep as well?
logger: new Logger<Dependency>(),
provider: storage)))
If, on the other hand, you would be using MS.DI as your DI Container, registration would be similar to the following:
services.AddScoped(_ => new RuntimeDepsStorage());
services.AddScoped<IRuntimeDepsProvider>(
c => c.GetRequiredService<RuntimeDepsStorage>());
services.AddScoped<IRuntimeDepsInitializer>(
c => c.GetRequiredService<RuntimeDepsStorage>());
// etc, your usual registrations here
I have a service layer that I am reusing (AKA Business Layer).
Here's an example of one of my services with an IMyContextFactory dependency, this returns an instance of IMyContext.
public class MyService : IMyService
{
private IMyContextFactory DbContextFactory;
public MyService(IMyContextFactory dbContextFactory)
{
this.DbContextFactory = dbContextFactory;
}
public DoSomething(int id)
{
// Get instance of the db for use
IMyContext dbContext = this.DbContextFactory.CreateMyDbContext();
// Use the business layer for something
var user = dbContext.Set<User>().Find(id);
}
}
I am using the Ninject Factory extension.
Is it possible to make the IMyContextFactory to return the same instance of IMyContext every time?
Background
Originally I was injecting IMyDbContext straight into the service without the factory and I had this InRequestScope() when initialized by my ASP.NET MVC website.
But now I am making use of the service it in a Windows Service too and I don't want my DbContext to become bloated because of frequent looping. I didn't want my service to be newed up for every request either, so that's why I thought a factory within the service would do the trick.
I need the best of InRequestScope() and a new instance every time depending on the configuration. I already have a separate config for ASP.NET and for the Windows Service - it's just how I get a singleton each time from the factory.
I'm not fully proficient with Ninject, but according to this page https://github.com/ninject/Ninject.Extensions.Factory/wiki/Factory-interface it seems that the instance returned by the factory is retrieved from the IResolutionRoot.
My take would be that you have to register your IMyContext concrete type with a singleton lifetime type.
(But it seems that it's not that of a good idea to not destroy your context, according to Erik Fukenbusch's comment)
I am using Entity Framework code first in my data layer using the repository pattern. I'm currently designing my WCF web services to connect to the data layer and I'm just a little confused about how to link up with the data layer.
In my test project for the data layer I create a new DbContext class for each test, wrap that in a using block, within that I create the repository class, passing in the context as the constructor parameter. I can then call my methods on the repository to get the data back.
Is this correct for a start and then do I do the same in the WCF service methods?
Eg would I have
public class UserService : IUserService
{
public bool CheckEmailAvailability(string email)
{
try
{
using (var context = new MyDbContext())
{
var repository = new UserDataRepository(context);
var emailAvailable =
repository.GetItems().Count(
u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase)) == 0;
return emailAvailable;
}
}
}
}
Or am I using the context/repository concept wrong?
It also strikes me that it would be handy to use DI here so I could mock the data context/repository objects in a WCF service test project. Is this something usually done and if so, does anyone have any links to an example or tutorial on this?
First of all, yes it would be better to inject the repository, or (if your chosen DI framework is unable to resolve them) a factory for the repository.
Additionally it might be a good idea to remove the idea of the context from your service. To my mind the repository and it's helpers should deal with the context, and if necessary with sharing the context between various DB calls required to assemble your entities. Then the services can request entities from the repositories without worrying about whether they're being source from a DB or some other data-store.
public class UserService: IUserService
{
IUserRepository userRepository;
... // ctor to inject repository
public bool CheckEmailAvailability(string email)
{
var emailAvailable = !userRepository.GetUserEmails().Any(u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase));
return emailAvailable;
}
}
public class UserRepository: IUserRepository
{
...
public IEnumerable GetUserEmails()
{
// actually this context should be handled more centrally, included here for sake of illustration
using (var context = new MyDbContext())
{
return repository.GetItems();
}
}
}
Finally, with regard to WCF services, I'm not certain what the best advice is. I've seen code where WCF services were created in the middle of business logic, which was awful, but a limitation of the oldish WPF code-base and limited DI. The better situations are where a ChannelFactory or service factory can be injected into your service layer. You may find this answer on Dependency Injection wcf helpful.
And as always, if you're planning to TDD your code, I'd definitely recommend wrapping the intersection points between layers of your application in interfaces so that they're easier to mock out. It sounds like you've got the right idea there.
this question is a follow-up of this question i posted last weekend.
As of now, i have something like this in my service layer which talks with UI in MVC application.
IDepartmentService deptService = kernel.Get<IDepartmentService>();
IList<Department> deptList = deptService.GetAllDepartments();
Everything is fine and DI is working as expected. However, for some reason if i decide to use Structuremap then my entire service layer needs to be changed. How do i abstract it out so that a change in DI tool wont affect my service layer or has minimum impact.
However, for some reason if i decide to use Structuremap then my
entire service layer needs to be changed.
That's not true. As shown in the previous thread the Service Layer doesn't know anything about the DI framework.
You should have a layer called composition root. This is the only layer which is aware of the DI framework and all the underlying layers. This is where you are doing the composition. So if you change the DI framework, the only place you need to make changes is in the composition root.
So you should absolutely get rid of kernel.Get<> calls from your service. Right now you are using Service Locator and not Dependency Injection. Service Locator is an anti-pattern. Your service layer should look like this:
public class MyService
{
private readonly ISomeDependency dependency;
public MyService(ISomeDependency dependency)
{
this.dependency = dependency;
}
public void SomeMethod()
{
// do something with the dependency here
}
}
instead of:
public class MyService
{
private readonly ISomeDependency dependency;
public MyService()
{
this.dependency = kernel.Get<ISomeDependency>();
}
public void SomeMethod()
{
// do something with the dependency here
}
}
I am enjoying creating and hosting WCF services.
Up until now I can create services defining contracts for the service and data (interfaces) and defining hosts and configuration options to reach them (endpoint specifications).
Well, consider this piece of code defining a service and using it (no mention for endpoints that are defined in app.config not shown here):
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
using (ServiceHost host = new ServiceHost(typeof(MyService))) {
host.Open();
...
host.Close();
}
}
}
Well, this structure is good when creating something that could be called a Standalone service.
What if I needed my service to use objects of a greater application.
For example I need a service that does something basing on a certain collection defined somewhere in my program (which is hosting the service). The service must look into this collection and search and return a particular element.
The list I am talking about is a list managed by the program and edited and modified by it.
I have the following questions:
1) How can I build a service able to handle this list?
I know that a possible option is using the overloaded ServiceHost constructor accepting an Object instead of a Type service.
So I could pass my list there. Is it good?
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
private List<> myinternallist;
public MyService(List<> mylist) {
// Constructing the service passing the list
}
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
List<> thelist;
...
MyService S = new MyService(thelist)
using (ServiceHost host = new ServiceHost(S)) {
host.Open();
...
host.Close();
// Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface)
}
}
}
This example should clarify.
Is it the good way of doing? Am I doing right?
2) How to handle conflicts on this shared resource between my service and my application?
When my application runs, hosting the service, my application can insert items in the list and delete them, the same can do the service too. Do I need a mutex? how to handle this?
Please note that the concurrency issue concerns two actors: the main application and the service. It is true that the service is singleton but the application acts on the list!!!
I assume that the service is called by an external entity, when this happens the application still runs right? Is there concurrency in this case???
Thankyou
Regarding point 2, you can use Concurrent Collections to manage most of the thread safety required.
I'm not sure what you mean by point 1. It sounds like you're describing basic polymorphism, but perhaps you could clarify with an example please?
EDIT: In response to comments you've made to Sixto's answer, consider using WCF's sessions. From what you've described it sounds to me like the WCF service should be sat on a seperate host application. The application you are using currently should have a service reference to the service, and using sessions would be able to call an operation mimicking your requirement for instantiating the service with a list defined by the current client application.
Combine this with my comment on exposing operations that allow interaction with this list, and you'll be able to run multiple client machines, working on session stored Lists?
Hope that's explained well enough.
Adding the constructor to MyService for passing the list certainly will work as you'd expect. Like I said in my comment to the question however, the ServiceHost will only ever contain a single instance of the MyService class so the list will not be shared because only one service instance will consume it.
I would look at a dependency injector (DI) container for WCF to do what you are trying do. Let the DI container provide the singleton list instance to your services. Also #Smudge202 is absolutely correct that using the Concurrent Collection functionality is what you need to implement the list.
UPDATE based on the comments thread:
The DI approach would works by getting all of an object's dependencies from the DI container instead of creating them manually in code. You register all the types that will be provided by the container as part of the application start up. When the application (or WCF) needs a new object instance it requests it from the container instead of "newing" it up. The Castle Windsor WCF integration library for example implements all the wiring needed to provide WCF a service instance from the container. This posts explains the details of how to use the Microsoft Unity DI container with WCF if you want to roll your own WCF integration.
The shared list referenced in this question would be registered in the container as an already instantiated object from your application. When a WCF service instance is spun up from the DI container, all the constructor parameters will be provided including a reference to the shared list. There is a lot of information out there on dependency injection and inversion of control but this Martin Fowler article is a good place to start.