So based on this question (here), of which I asked last week, I decided to go and have a look into the Castle project and use the Castle.Facilities.NHibernateIntegration facility.
I spent the best part of two days messing around with it and have come to the same issue: NHibernate Thread-Safe Sessions. I was hoping, out of the box, the built in ISessionManager was smart enough to handle threading, which is the reason why I decided to implement it.
In the very sparse documentation on that particular project it mentions that calling ISessionManager.OpenSession is much the same as calling session.GetCurrentSession. From this I gather there is no way for me to, force open, a new seperate session.
So has anyone the solution for me or any ideas how I can work with this issue?
(I know most people are going to say only work with one thread, but honestly think outside the box, some tools and routines automatically spawn a new thread. For instance, log4net and sessionstatestore. You can't just assume there will only be one thread, associated, with the current request.)
Notes:
I'm working on the web model with .NET 4 web application.
I invoke and resolve the Windsor container in the usual, documented way and let the container resolve the session manager. I do this in both threads.
Here is my Castle NHibernate config:
Code:
<facility id="nhibernate" isWeb="true" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
<factory id="nhibernate.factory">
<settings>
<item key="connection.connection_string">#{NHibernateConnectionString}</item>
<item key="connection.driver_class">#{NHibernateDriver}</item>
<item key="connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
<item key="dialect">#{NHibernateDialect}</item>
<item key="generate_statistics">true</item>
<item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
<item key="show_sql">true</item>
</settings>
<assemblies>
<assembly>Gigastence.Base.Common</assembly>
</assemblies>
</factory>
Here is my example DAO
Code:
public class NHibernateDao : INHibernateDao
{
private ISessionManager sessionManager;
public NHibernateDao(ISessionManager sessionManager)
{
this.sessionManager = sessionManager;
}
public void Append(LoggingEvent loggingEvent)
{
using (IStatelessSession session = sessionManager.OpenStatelessSession())
{
using (ITransaction tran = session.BeginTransaction())
{
Log data = new Log
{
Id = Guid.NewGuid(),
Date = loggingEvent.TimeStamp,
Level = loggingEvent.Level.ToString(),
Logger = loggingEvent.LoggerName,
Thread = loggingEvent.ThreadName,
Message = loggingEvent.MessageObject.ToString()
};
if (loggingEvent.ExceptionObject != null)
{
data.Exception = loggingEvent.ExceptionObject.ToString();
}
session.Insert(data);
tran.Commit();
}
}
}
}
And how I call the DAO. Note: This is on the newly spawned thread which is out of my hands.
Code:
public class NHibenateAppender : AppenderSkeleton
{
protected override void Append(LoggingEvent loggingEvent)
{
if(IoC.IsInitialized)
{
var NHibernateLogger = IoC.Resolve<INHibernateDao>();
NHibernateLogger.Append(loggingEvent);
}
}
}
If you want full control of the session, I believe that the NHibernateFacility actually registers the underlying ISessionFactory to the Windsor kernel.
From that, you can invoke sessionFactory.OpenSession() which I think should always return a new session.
I honestly don't really see what ISessionManager brings to the party...
Have a look at this link!
https://github.com/haf/Castle.Facilities.NHibernate/wiki
It might solve your multi-threaded problems, as it differs in intention to the previous facility; this one lets you keep a session-per-transaction rather than one per request. As such, the multi-threaded issue is avoided and it would work equally well from your appender.
In the code, this is because the .Net has a CallContext static class that knows about what thread you're on (but ties it to your call context rather than thread-static).
We were running into this problem a lot when using the SessionPerWebRequest pattern and then forking worker threads, which as you say, cannot be helped in some situations.
The trick is as jishi says; instead of pulling the session from Func<ISession> or ISessionManager, you need to get access to ISessionFactory.
Unfortunately for me, this wasn't as simple as injecting it through the constructor and having Windsor resolve it - it isn't registered as part of the installer as jishi said (unless I'm missing something). However, it is accessible through an installer callback:
public class NHibernateInstaller : INHibernateInstaller, IDatabaseInstaller
{
...
public void Registered(ISessionFactory factory)
{
SessionFactoryStore.Set(SessionFactoryKey, factory);
}
}
Where SessionFactoryStore is a singleton repository for storing your factories (in the case where you may have multiple factories, spread across clients, like me).
[Singleton]
public class SessionFactoryStore: ISessionFactoryStore
{
Dictionary<string, ISessionFactory> SessionFactories { get; set; }
public SessionFactoryStore()
{
SessionFactories = new Dictionary<string, ISessionFactory>();
}
public void Set(string key, ISessionFactory factory)
{
lock (SessionFactories)
{
if (!SessionFactories.ContainsKey(key)) SessionFactories.Add(key, factory);
}
}
public ISessionFactory Get(string key)
{
return SessionFactories.ContainsKey(key) ? SessionFactories[key] : null;
}
}
Then wherever you implement your unit of work pattern, or similar, just perform a test to see if you are running in a normal, or threaded state:
[PerWebRequest]
public class UnitOfWork : IUnitOfWork
{
private IGenericFactory GenericFactory { get; set; }
private Func<ISession> Session { get; set; }
private ISessionFactoryStore SessionFactoryStore { get; set; }
private ISession GetSession(bool isThreaded)
{
if (!isThreaded)
return Session();
else
return SessionFactoryStore.Get("YourFactoryKey").OpenSession();
}
public UnitOfWork(Func<ISession> session, ISessionFactoryStore sessionFactoryStore) {
Session = session;
SessionFactoryStore = sessionFactoryStore;
}
...
}
Hey presto, thread-safe ISession using NHibernateIntegration.
Related
I am toying with Swashbuckle.Examples package (3.10.0) in an ASP.NET MVC project. However, I cannot make request examples appear within the UI.
Configuration (SwaggerConfig.cs)
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c => {
c.SingleApiVersion("v1", "TestApp.Web");
c.IncludeXmlComments(string.Format(#"{0}\bin\TestApp.Web.xml", System.AppDomain.CurrentDomain.BaseDirectory));
c.OperationFilter<ExamplesOperationFilter>();
c.OperationFilter<DescriptionOperationFilter>();
c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
})
.EnableSwaggerUi(c => { });
}
Request example classes
public class EchoRequestExample : IExamplesProvider
{
public object GetExamples()
{
return new EchoInput { Value = 7 } ;
}
}
public class EchoInput
{
public int Value { get; set; }
}
Action
[HttpGet]
[Route("Echo")]
[CustomApiAuthorize]
[SwaggerRequestExample(typeof(EchoInput), typeof(EchoRequestExample))]
[ResponseType(typeof(EchoServiceModel))]
public HttpResponseMessage Echo([FromUri] EchoInput model)
{
var ret = new EchoServiceModel
{
Username = RequestContext.Principal.Identity.Name,
Value = value
};
return Request.CreateResponse(HttpStatusCode.OK, ret);
}
Swagger UI shows xml comments and output metadata (model and an example containing default values), but shows no request example. I attached to process and EchoRequestExample.GetExamples is not hit.
Question: How to make SwaggerRequestExample attribute work in ASP.NET MVC 5?
Note: Windows identity is used for authorization.
I received an answer from library owner here:
Swagger request examples can only set on [HttpPost] actions
It is not clear if this is a design choice or just a limitation, as I find [HttpGet] examples also relevant.
I know the feeling, lot's of overhead just for an example, I struggle with this for a while, so I created my own fork of swashbuckle, and after unsuccessful attempts to merge my ideas I ended up detaching and renaming my project and pushed to nuget, here it is: Swagger-Net
An example like that will be:
[SwaggerExample("id", "123456")]
public IHttpActionResult GetById(int id)
{
Here the full code for that: Swagger_Test/Controllers/IHttpActionResultController.cs#L26
Wondering how that looks like on the Swagger-UI, here it is:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=IHttpActionResult#/IHttpActionResult/IHttpActionResult_GetById
I've installed MVC Site Map Provider for MVC5 and just used everything out of the the box. It works fine. Now I want to implement roles based menu trimming so assuming my controller:
public class Home: Controller
{
[Authorize(Roles="Admin")]
public ActionResult Index()
{
return View();
}
}
Now basically only Admin role users can see the menu. Perfect works fine.
Also to implement this I added to my web.config this line:
<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true" />
The problem is that it works but it's slow. It takes about 7 seconds for the page to load. If I remove the web.config line, basically removing menu trimming based on roles it takes ~300ms for the page to load. Something is wrong in here.
Any ideas why my menu trimming based on roles is slow? I haven't done any customizations.
The security trimming feature relies on creating a controller instance for every node in order to determine if the current user context has access.
The most likely cause of this slowness is that your controllers (or their base class) have too much heavy processing happening in the constructor.
public class HomeController
{
public HomeController() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
};
}
The above example will add 300 ms to the page load time for every node that represents an action method in the HomeController. If your other controllers also have heavy processing during instantiation, they will also add additional time to each page load.
When following DI best practices, this is not an issue because heavy processing takes place in external services after the controller instance is created.
public interface IHeavyProcessingService
{
IProcessingResult DoSomethingExpensive();
}
public class HeavyProcessingService : IHeavyProcessingService
{
public HeavyProcessingService() {
}
public IProcessingResult DoSomethingExpensive() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
}
}
public class HomeController
{
private readonly IHeavyProcessingService heavyProcessingService;
// The constructor does no heavy processing. It is deferred until after
// the instance is created by HeavyProcessingService.
// The only thing happening here is assignment of dependencies.
public HomeController(IHeavyProcessingService heavyProcessingService) {
if (heavyProcessingService == null)
throw new ArgumentNullException("heavyProcessingService");
this.heavyProcessingService = heavyProcessingService;
};
public ActionResult Index()
{
var result = this.heavyProcessingService.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Contact()
{
return View();
}
}
Notice in the above example that no heavy processing happens in the constructor? This means that creating an instance of HomeController is very cheap. It also means that action methods that don't require the heavy processing to happen (as in About() and Contact() in the example) won't take the hit of heavy processing required by Index().
If not using DI, MVC still requires that a new controller instance be created for each request (controller instances are never shared between users or action methods). Although, in that case it is not as noticeable on a per user basis because only 1 instance is created per user. Basically, MvcSiteMapProvider is slowing down because of a pre-existing issue with your application (which you can now fix).
Even if you are not using DI, it is still a best practice to defer heavy processing until after the controller instance is created.
public class HomeController
{
private readonly IHeavyProcessingService heavyProcessingService;
public HomeController() {
this.heavyProcessingService = new HeavyProcessingService();
};
public ActionResult Index()
{
var result = this.heavyProcessingService.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
}
But if moving heavy processing into external services in your application is not an option, you can still defer processing until its needed by moving the processing into another method so it is not too expensive to create controller instances.
public class HomeController
{
public HomeController() {
};
private IProcessingResult DoSomethingExpensive() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
}
public ActionResult Index()
{
var result = this.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
}
Although there is a bug posted for Route values not preserved correctly in v4?
But looks like it was fixed in version 4 next release.
Another Workaround to fix this problem is cache here is a related article.
MVC siteMap provider cache
Having an huge customers profile page if two or more users start using same page and start editing big change will happen in my database so planing to implement Threads concept where only one user can use that customer page
i'm aware about threads concept but confused how to implement it
hope i need to use Singleton class as well
Any suggestion or Logic's will be helpful
I'm using Struts,Hibernate frame work
You may use application context to store a flag variable. Action will use its value to allow only one simultaneous execution.
public class TestAction extends ActionSupport implements ApplicationAware {
private static final String APP_BUSY_KEY = "APP_BUSY";
Map<String, Object> map;
#Override
public void setApplication(Map<String, Object> map) {
this.map = map;
}
#Override
public String execute() throws Exception {
if (map.containsKey(APP_BUSY_KEY)) {
return ERROR;
} else {
map.put(APP_BUSY_KEY, "1");
try {
// action logic here
} finally {
map.remove(APP_BUSY_KEY);
}
return SUCCESS;
}
}
}
If you plan to implement similar logic for two requests (lock after displaying values and release lock after submitting new values) then logic will be more complex and you will also need to handle lock release after timeout.
I'm looking for recommendations on how to approach the following design problem (using a fictitious example based on stackoverflow). I'd trying to avoid an anemic domain model and seek general "best-practice" advice for this type of case.
Scenario:
Suppose a new feature is being developed for stackoverflow that sends an email notification to a question's owner whenever his/her question receives 10 upvotes.
The domain object model is something like this:
public class Question
{
string Question { get; set; }
IList<Votes> Upvotes { get; set; }
User Owner { get; set; }
public void AddUpvote(Vote upvote)
{
Upvotes.Add(upvote);
}
}
Potential Implementations:
Change AddUpvote() to take an IEmailerService parameter and perform the logic within the AddUpvote() method.
public void AddUpvote(Vote upvote, IEmailerService emailer)
{
Upvotes.Add(upvote);
if ( Upvotes.Count == 10 )
{
emailer.Send(Owner.EmailAddr);
}
}
Detect this state within AddUpvote() and have AddUpvote() resolve an IEmailService from an IoC container (instead of passing the IEmailerService as a parameter).
Detect this state in the external service object that invokes question.AddUpvote().
public void UpvoteClickHandler(Question question)
{
question.AddUpvote(new Upvote());
if ( question.Upvotes.Count == 10 )
{
_emailer.Send(question.Owner.EmailAddr);
}
}
Your better solution here!
You really don't want to mix these two together since they have separate concerns. Let the Question class care about questions and the message service care about what to do when the voting hits 10, or 20, or 100 or...
The following example is meant for demonstration purposes only, but you will get the point. There is a clear separation of concerns, so the Question class doesn't have to change if the requirements for sending messages changes. Remember according to the SOLID principles, a class should only have one reason to change.
public class Question
{
public string Description { get; set; }
public Int32 Votes { get; set; }
public User Owner { get; set; }
public event EventHandler<QuestionEventArgs> OnUpvote;
private void RaiseUpvoteEvent(QuestionEventArgs e)
{
var handler = OnUpvote;
if (handler != null) handler(this, e);
}
public void Upvote()
{
Votes += 1;
RaiseUpvoteEvent(new QuestionEventArgs(this));
}
}
public class MessageService
{
private Question _question;
public MessageService(Question q)
{
_question = q;
q.OnUpvote += (OnUpvote);
}
private void OnUpvote(object sender, QuestionEventArgs e)
{
if(e.Question.Votes > 10)
SendMessage(e.Question.Owner);
}
}
public class QuestionEventArgs: EventArgs
{
public Question Question { get; set; }
public QuestionEventArgs(Question q)
{
Question = q;
}
}
So there you have it. There are a lot of other ways to accomplish this, but the event model is a great way to go, and it accomplishes the separation of concerns you want in your implementation in order to make maintenance earlier.
Both options 1) and 2) jump out as being the wrong place to send out an email. A Question instance shouldn't know these two things:
It shouldn't know about the policy, ie when to send out an email.
It shouldn't know about the mechanics of notification for a policy, ie the email service.
I know that this is a matter of taste, but you're tying in the Question closely with both a policy as well as the mechanism to send out an email. It would be really hard to move this Question class to another project (like ServerFault, which is StackOverflow's sister site for instance)
I'm interested in this question, because I'm creating a notification system for a Help Desk that I am building. This is what I did in my system:
Create a NotificationManager (Basically, completely move the concern of notifications to a separate class).
public Class NotificationManager
{
public void NotificationManager(NotificationPolicy policy, IEmailService emailer)
{
}
}
I then did something along the lines of this (The UpvoteClickHandler has a dependency to a NotificationManager instance):
public void UpvoteClickHandler(Question question)
{
question.AddUpvote(new Upvote());
_notificationManager.Notify(Trigger.UpvoteAdded, question);
}
All the UpvoteClickHandler does is tell NotificationManager that an upvote was added to question and let NotificationManager determine whether and how it should send out an email.
The answer depends on your fundamental approach to application and object design. And (edit here) what you view as your most important trait of the system. Looks like you have data, questions, and business rules, up votes. Not question objects at all. So you should treat your data as data and allow data tools to work on them, by not mixing behavior into them. Traditional object design would have all the behaviors and data in the object, so sending eMail would belong in the object. (option 1 and 2) I guess this is the black box, or self contained object approach. Modern practices, as I've come to learn, has objects as simple data holders. Which are meant to be moved around, persisted, transformed and have stuff done to them. Perhaps living as little more than structs in C. The behavior comes from the services and transformations that are applied to the simple objects.
HI all,
In my opinion "sends an email notification to a question's owner whenever his/her question receives 10 upvotes" is domain logic and therfore it should be into domain object, in order to avoid an anemic domain.
It's the action of sending the email (i.e. communicate with smtp server) that MUST go into the infrastructure layer.
So i think that option 1 is not totally wrong. Keep in mind that you can always test your object by passing a mock implementation of the IEmailerService.
Best Regards,
Stefano
I was looking at Prism EventAggregator and its' great. I part i was most concerned was its capability to marshal thread correctly to UI thread.
I was wondering if i can use this capability to provide module developers a class which could be used to create threads in a similar way as BackgroundWorker. Interface of class can be somewhat similar to
public interface IMyTask
{
event DoWorkEventHandler DoWork;
event RunWorkerCompletedEventHandler RunWorkerCompleted;
void RunTaskAsync(object obj);
}
I have kept types similar to backgroundworker for better understanding. In implementation i am registering taskstart and taskcomplete events
public class TaskStartEventPayload
{
public SubscriptionToken token { get; set; }
public object Argument { get; set; }
}
public class TaskStartEvent : CompositePresentationEvent<TaskStartEventPayload>
{
}
public class TaskCompleteEventPayload
{
public SubscriptionToken token { get; set; }
public object Argument { get; set; }
public object Result { get; set; }
}
public class TaskCompleteEvent : CompositePresentationEvent<TaskCompleteEventPayload>
{
}
In the constructor for the MyTask class i take which thread the completion is required on as
public MyTask(IEventAggregator eventAggregator, bool isUICompletion)
{
if (eventAggregator == null)
{
throw new ArgumentNullException("eventAggregator");
}
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<TaskStartEvent>().Subscribe(TaskStartHandler, ThreadOption.BackgroundThread, false, new Predicate<TaskStartEventPayload>(StartTokenFilter));
if(isUICompletion)
_token = _eventAggregator.GetEvent<TaskCompleteEvent>().Subscribe(TaskCompleteHandler, ThreadOption.UIThread,true,new Predicate<TaskCompleteEventPayload>(CompleteTokenFilter));
else
_token = _eventAggregator.GetEvent<TaskCompleteEvent>().Subscribe(TaskCompleteHandler, ThreadOption.BackgroundThread, true, new Predicate<TaskCompleteEventPayload>(CompleteTokenFilter));
}
here i am registering with filters where filter function returns the event only if it has Payload has same token as while got while subscribing.
further I use
public void RunTaskAsync(object obj)
{
//create payload
_eventAggregator.GetEvent<TaskStartEvent>().Publish(payload);
}
public void TaskStartHandler(TaskStartEventPayload t)
{
//fire dowork and create payload
DoWork(this, args);
_eventAggregator.GetEvent<TaskCompleteEvent>().Publish(tc);
}
public void TaskCompleteHandler(TaskCompleteEventPayload t)
{
RunWorkerCompleted(this, args);
}
This class can be used as
MyTask et = new MyTaskagg, true);
et.DoWork += new System.ComponentModel.DoWorkEventHandler(et_DoWork);
et.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(et_RunWorkerCompleted);
et.RunTaskAsync("Test");
Benefit I see in this approach is
1. It uses threadpool so no overhead of creating threads as in backgroundWorker.
2. Proper thread marshalling in case RunWorkerCompleted to be executed on UI thread.
Please advice if this would be correct to use eventaggregator as Threader.
This will work, although it's code you have to debug for very little performance gain. Micro-optimizing is rarely worth the effort and support costs in my opinion.
EventAggregator is meant to be a message bus for your application and I typically prefer to use things for their original intention, lest I have to debug a lot of code, but that's my personal preference.
Event Aggregator is going to have to work a little harder than it is meant to cleaning up all of those subscriptions, which will likely exceed any performance gain you get from the thread pooling, but that is just a guess.