I am trying to implement proxy design pattern for caching services as below.
public interface IProductService
{
int ProcessOrder(int orderId);
}
public class ProductService : IProductService
{
public int ProcessOrder(int orderId)
{
// implementation
}
}
public class CachedProductService : IProductService
{
private IProductService _realService;
public CachedProductService(IProductService realService)
{
_realService = realService;
}
public int ProcessOrder(int orderId)
{
if (exists-in-cache)
return from cache
else
return _realService.ProcessOrder(orderId);
}
}
How do I to use IoC container (Unity/Autofac) to create real service and cached service objects as I can register IProductService to ProductService or CachedProductService but CachedProductService in turn requires a IProductService object (ProductService) during creation.
I am trying to arrive at something like this:
The application will target IProductService and request IoC container for an instance and depending on the configuration of the application (if cache is enabled/disabled), the application will be provided with ProductService or CachedProductService instance.
Any ideas? Thanks.
Without a container your graph would look like this:
new CachedProductService(
new ProductService());
Here's an example using Simple Injector:
container.Register<IProductService, ProductService>();
// Add caching conditionally based on a config switch
if (ConfigurationManager.AppSettings["usecaching"] == "true")
container.RegisterDecorator<IProductService, CachedProductService>();
Related
We are running a few Stateless Reliable Services and are having performance issues with service-to-service communication using the reverse proxy (http://localhost:19081/{app}/{svc}/bleh). Without getting into the details there, we are looking into using remoting as described here: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting
However, I am having a hard time figuring out how I would expose the API methods in the service type class, as they currently exist in our controllers. The controllers, via dependency injection, get the repository instances needed, etc..., so I'm spinning my wheels on how to get this accomplished without some sort of redundant instances or circular dependency.
I'm sitting here staring at this on "PersonService.cs":
internal sealed class PersonService: StatelessService, IPersonService
{
public PersonService(StatelessServiceContext context)
: base(context)
{ }
...
public PersonResponse GetPersonFromDb()
{
//lost here :(
}
Where my controller, which works fine, has:
public PersonController(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
...
public IActionResult GetPerson()
{
var personResponse = _dbRepository.GetPerson();
return new ObjectResult(personResponse);
}
D:
Can't you pass the repository to your service, similar to this?
public PersonService(StatelessServiceContext context, IPersonRepository personRepository)
: base(context)
{
_personRepository = personRepository;
}
public PersonResponse GetPersonFromDb()
{
var personResponse = _personRepository.GetPerson();
return personResponse;
}
I want to implement an annotation which registers classes (not instances of classes) with a factory as soon as the application is started. I am using Spring Framework 4.2.7.
Consider a system with a dashboard and multiple widgets. The dashboard has a configuration file which contains a list of widgets to display for the current user. When displayed it reads the configuration and creates the widgets. The widgets will receive additional parameters from the configuration.
Here is a bit of code illustrating this:
public class TestDashboard implements Dashboard {
public void dashboardPreDisplay() {
List<String> widgets = getWidgetList(/* current user in session */);
for (String widgetId : widgets) {
// create instance of DashboardWidget with given ID
DashboardWidget x = widgetFactory.createWidget(widgetId);
}
}
public List<String> getWidgetList(String user) {
// load list of IDs of DashboardWidgets to be displayed for the user
}
#Autowired
private WidgetFactory widgetFactory;
}
#Service
public class WidgetFactory {
public DashboardWidget createWidget(String widgetId) {
// look up Class<> of DashboardWidget with given id in widgetClasses
// construct and initialize DashboardWidget
}
private HashMap<String, Class<?>> widgetClasses;
}
When implementing my widgets I don't want to deal with registering the widget with the factory class. Ideally I would just annotate the widget like that:
#DashboardWidget(id = "uniqueId")
public class DashboardWidgetA implements DashboardWidget {
// ...
}
When the application starts it should scan the classpath for #DashboardWidget annotations and register the classes with the factory, so that the widgets can be constructed by giving the createWidget-method the id of the widget.
At the moment I am a little bit confused. I think Spring has every tool on board to achieve this behavior. But I cannot think of a way how to do it.
Do you have some advice for me?
Nothing prevents you to create your custom annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface DashboardWidget {}
Then you can annotate your Widget's classes and make them spring beans. You have to keep in mind if you want to have them as singletons (scope=singleton) , or separate instances per user (scope=prototype).
You have to implement:
public class WidgetInitializationListener implements ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext context = event.getApplicationContext();
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
String originalClassName = getOriginalClassName(beanDefinitionName, event);
if (originalClassName != null) {
Class<?> clazz = Class.forName(originalClassName);
if (hasWidgetAnnotation(clazz)) {
registerSomewhereYourWidget(context, beanDefinitionName, originalClassName);
}
}
}
}
private String getOriginalClassName(String name, ContextRefreshedEvent event) {
try {
ConfigurableListableBeanFactory factory =
(ConfigurableListableBeanFactory)event.getApplicationContext().getAutowireCapableBeanFactory();
BeanDefinition beanDefinition = factory.getBeanDefinition(name);
return beanDefinition.getBeanClassName();
} catch (NoSuchBeanDefinitionException e) {
LOG.debug("Can't get bean definition for : " + name);
return null;
}
}
So mostly here is nothing to do with spring except you just run through your beans to find annotated ones.
I have a custom dbcontext which name is Tracker-enabled DbContext (https://github.com/bilal-fazlani/tracker-enabled-dbcontext).I want to use it for audit log
And how can I implement EFRepository?
I implemented tracker-enabled-context but i cant solve how override sharp repo commit method.
public class HayEntities : TrackerContext
{
static HayEntities()
{
Database.SetInitializer<HayEntities>(null);
}
public HayEntities() : base(HayEntities)
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = true;
this.Configuration.ValidateOnSaveEnabled = false;
}
public DbSet<Dummy> Dummys{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DummyConfiguration());
} }
}
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
private readonly IRepository<DE.Dummy, long> _servisHasarRepository;
public DummyRepository (HayEntities hayEntities, ICachingStrategy<DE.Dummy, long> cachingStrategy = null)
{this.CachingEnabled = false;
_dummyRepository = new EfRepository<DE.Dummy, long>(hayEntities, cachingStrategy);
}
public void UpdateOrCreate() {
//In this area how can override save/commit method
}
}
You will want to tell SharpRepository to use an IoC provider to inject the DbContext. This will take care of getting the proper DbContext for your EfRepository.
If you want to control things based on the configuration and have custom repositories so you can implement your own mehods like UpdateOrCreate() then you would inherit from ConfigurationBasedRepository as you have in the example.
There are more details on setting up IoC with SharpRepository here: http://fairwaytech.com/2013/02/sharprepository-configuration/ (look in the "Entity Framework and Sharing the DbContext" section)
First look on NuGet for SharpRepository.Ioc.* to find the specific IoC you are using. If you are using StructureMap then you would do something like this.
In your StructureMap configuration:
// Hybrid (once per thread or ASP.NET request if you’re in a web application)
For<DbContext>()
.HybridHttpOrThreadLocalScoped()
.Use<HayEntities>()
.Ctor<string>("connectionString").Is(entityConnectionString);
Then you need to tell SharpRepository to use StructureMap by calling this in your startup code:
RepositoryDependencyResolver.SetDependencyResolver(new StructureMapDependencyResolver(ObjectFactory.Container));
After doing these things, then if you use EfRepository then it will know to ask StructureMap for the DbContext.
Now in your example above where you are using ConfigurationBasedRepository, I would suggest setting the caching in the configuration file instead of in code since you are using the configuration to load the repository. Since IoC is handling the DbContext you don't need to do anyhing with that and you can focus on the custom method you want to write.
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
public void UpdateOrCreate()
{
// You have access to the underlying IRepository<> which is going to be an EfRepository in your case assuming you did that in the config file
// here you can call Repository.Add(), or Reposiory.Find(), etc.
}
}
It appears that the update for mongoOperations do not trigger the events in AbstractMongoEventListener.
This post indicates that was at least the case in Nov 2014
Is there currently any way to listen to update events like below? This seems to be quite a big omission if it is the case.
MongoTemplate.updateMulti()
Thanks!
This is no oversight. Events are designed around the lifecycle of a domain object or a document at least, which means they usually contain an instance of the domain object you're interested in.
Updates on the other hand are completely handled in the database. So there are no documents or even domain objects handled in MongoTemplate. Consider this basically the same way JPA #EntityListeners are only triggered for entities that are loaded into the persistence context in the first place, but not triggered when a query is executed as the execution of the query is happening in the database.
I know it's too late to answer this Question, I have the same situation with MongoTemplate.findAndModify method and the reason I needed events is for Auditing purpose. here is what i did.
1.EventPublisher (which is ofc MongoTemplate's methods)
public class CustomMongoTemplate extends MongoTemplate {
private ApplicationEventPublisher applicationEventPublisher;
#Autowired
public void setApplicationEventPublisher(ApplicationEventPublisher
applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
//Default Constructor here
#Override
public <T> T findAndModify(Query query, Update update, Class<T> entityClass) {
T result = super.findAndModify(query, update, entityClass);
//Publishing Custom Event on findAndModify
if(result!=null && result instanceof Parent)//All of my Domain class extends Parent
this.applicationEventPublisher.publishEvent(new AfterFindAndModify
(this,((Parent)result).getId(),
result.getClass().toString())
);
return result;
} }
2.Application Event
public class AfterFindAndModify extends ApplicationEvent {
private DocumentAuditLog documentAuditLog;
public AfterFindAndModify(Object source, String documentId,
String documentObject) {
super(source);
this.documentAuditLog = new DocumentAuditLog(documentId,
documentObject,new Date(),"UPDATE");
}
public DocumentAuditLog getDocumentAuditLog() {
return documentAuditLog;
}
}
3.Application Listener
public class FindandUpdateMongoEventListner implements ApplicationListener<AfterFindAndModify> {
#Autowired
MongoOperations mongoOperations;
#Override
public void onApplicationEvent(AfterFindAndModify event) {
mongoOperations.save(event.getDocumentAuditLog());
}
}
and then
#Configuration
#EnableMongoRepositories(basePackages = "my.pkg")
#ComponentScan(basePackages = {"my.pkg"})
public class MongoConfig extends AbstractMongoConfiguration {
//.....
#Bean
public FindandUpdateMongoEventListner findandUpdateMongoEventListner(){
return new FindandUpdateMongoEventListner();
}
}
You can listen to database changes, even the changes completely outside your program (MongoDB 4.2 and newer).
(code is in kotlin language. same for java)
#Autowired private lateinit var op: MongoTemplate
#PostConstruct
fun listenOnExternalChanges() {
Thread {
op.getCollection("Item").watch().onEach {
if(it.updateDescription.updatedFields.containsKey("name")) {
println("name changed on a document: ${it.updateDescription.updatedFields["name"]}")
}
}
}.start()
}
This code only works when replication is enabled. You can enable it even when you have a single node:
Add the following replica set details to mongodb.conf (/etc/mongodb.conf or /usr/local/etc/mongod.conf or C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg) file
replication:
replSetName: "local"
Restart mongo service, Then open mongo console and run this command:
rs.initiate()
I have read as many of the posts on Stackoverflow as I can find with regards the use of a Unit of Work pattern within
an ASP.Net MVC 3 application which includes a Business Layer. However, I still have a couple of questions with
regards this topic and would greatly appreciate any feedback people can give me.
I am developing an ASP.Net MVC 3 Web application which uses EF 4.1. I will be using both the Repository and
Unit of Work Patterns with this project similar to how they are used in this great tutorial
The difference in my project is that I need to also include a Business Layer (separate project in my solution) in order to
carry out the various business rules for the application. The tutorial mentioned above does not have a Business layer, and
therefore creates an instance of the Unit of Work class from the controller
public class CourseController : Controller
{
private UnitOfWork unitOfWork = new UnitOfWork();
However, my question is, where should I create the instance of the Unit of Work class if I have a Business Layer?
I personally think it should be created in my controller and then injected into the Business Layer like so:
public class PeopleController : Controller
{
private readonly IUnitOfWork _UoW;
private IPersonService _personService;
public PeopleController()
{
_UoW = new UnitOfWork();
_personService = new PersonService(_UoW);
}
public PeopleController(IUnitOfWork UoW, IPersonService personService)
{
_UoW = UoW;
_personService = personService;
}
public ActionResult Edit(int id)
{
Person person = _personService.Edit(id);
return View(person);
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private BlogEntities _context = new BlogEntities();
private PersonRepository personRepository = null;
public IPersonRepository PersonRepository
{
get
{
if (this.personRepository == null)
{
this.personRepository = new PersonRepository(_context);
}
return personRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
public class PersonService : IPersonService
{
private readonly IUnitOfWork _UoW;
public PersonService(IUnitOfWork UoW)
{
_UoW = UoW;
}
public Person Edit(int id)
{
Person person = _UoW.PersonRepository.GetPersonByID(id);
return person;
}
public class PersonRepository : IPersonRepository
{
private readonly BlogEntities _context;
public PersonRepository(BlogEntities context)
{
_context = context;
}
public Person GetPersonByID(int ID)
{
return _context.People.Where(p => p.ID == ID).Single();
}
I have read others saying that the Unit of Work instantiation should not be in the Controller, but created in the Service Layer
instead. The reason why I am not so sure about this approach is because my Controller may have to use several different
Service Layers in one business transaction, and if the Unit of Work instance was created inside each Service, it would result in several
Unit of Work instances being created, which defeats the purpose, ie, one Unit of Work per business transaction.
Maybe what I have explained above is wrong, but if so, I would greatly appreciate if someone could put me right.
Thanks again for your help.
I think you have a couple of changes to make:.
Allow your DI container to inject a UnitOfWork instance into your Service classes in their constructors, and leave it out of your Controller altogether.
If your DI container supports it (Ninject does, for example), configure your UnitOfWork to be managed on a per-request basis; this way your services will be handed a distinct UnitOfWork for each request, and you're all done. Or...
If your DI container does not support per-request lifetimes, configure it to manage the UnitOfWork as a singleton, so every Service class gets the same instance. Then update your UnitOfWork to store its Entities object in a data store which stores objects on a per-request basis, for example in HttpContext.Current.Items, as described here.
Edit 1
Regarding where the UnitOfWork should be injected; I'd say the Service layer is the correct place. If you imagine your system as a series of layers where the outer layers deal with user interactions and the lower layers deal with data storage, each layer should become less concerned with users and more concerned with data storage. UnitOfWork is a concept from one of the 'lower-level' layers and Controller is from a higher-level layer; your Service layer fits between them. It therefore makes sense to put the UnitOfWork into the Service class rather than the Controller.
Edit 2
To elaborate on the UnitOfWork creation and it's relationship to HttpContext.Current.Items:
Your UnitOfWork would no longer hold a reference to an Entities object, that would be done through the HttpContext object, injected into the UnitOfWork behind an interface like this:
public interface IPerRequestDataStore : IDisposable
{
bool Contains(string key);
void Store<T>(string key, T value);
T Get<T>(string key);
}
The HttpContext object would then implement IPerRequestDataStore like this:
public class StaticHttpContextPerRequestDataStore : IPerRequestDataStore
{
public bool Contains(string key)
{
return HttpContext.Current.Items.Contains(key);
}
public void Store<T>(string key, T value)
{
HttpContext.Current.Items[key] = value;
}
public T Get<T>(string key)
{
if (!this.Contains(key))
{
return default(T);
}
return (T)HttpContext.Current.Items[key];
}
public void Dispose()
{
var disposables = HttpContext.Current.Items.Values.OfType<IDisposable>();
foreach (var disposable in disposables)
{
disposable.Dispose();
}
}
}
As an aside, I've called it StaticHttpContextPerRequestDataStore as it uses the static HttpContext.Current property; that's not ideal for unit testing (another topic altogether), but at least the name indicates the nature of its dependency.
Your UnitOfWork then passes the IPerRequestDataStore it's given to each of its Repository objects so they can access the Entities; this means that no matter how many UnitOfWork instances you create, you'll use the same Entities object throughout a request because it's stored and retrieved in the IPerRequestDataStore.
You'd have an abstract base Repository which would use its IPerRequestDataStore to lazy-load its Entities object like this:
public abstract class RepositoryBase : IDisposable
{
private readonly IPerRequestDataStore _dataStore;
private PersonRepository personRepository;
protected RepositoryBase(IPerRequestDataStore dataStore)
{
this._dataStore = dataStore;
}
protected BlogEntities Context
{
get
{
const string contextKey = "context";
if (!this._dataStore.Contains(contextKey))
{
this._dataStore.Store(contextKey, new BlogEntities());
}
return this._dataStore.Get<BlogEntities>(contextKey);
}
}
public void Dispose()
{
this._dataStore.Dispose();
}
}
Your PeopleRepository (for example) would look like this:
public class PeopleRepository : RepositoryBase, IPersonRepository
{
public PeopleRepository(IPerRequestDataStore dataStore)
: base(dataStore)
{
}
public Person FindById(int personId)
{
return this.Context.Persons.FirstOrDefault(p => p.PersonId == personId);
}
}
And finally, here's the creation of your PeopleController:
IPerRequestDataStore dataStore = new StaticHttpContextDataStore();
UnitOfWork unitOfWork = new UnitOfWork(dataStore);
PeopleService service = new PeopleService(unitOfWork);
PeopleController controller = new PeopleController(service);
One of the central concepts here is that objects have their dependencies injected into them via their constructors; this is generally accepted as good practice, and more easily allows you to compose objects from other objects.