How to pass some custom parameters to SendCompleted event in Mailkit.SmtpClient?
I expect something like in System.Net.Mail that I can easily pass some custom parameters and doing some process inside the SendCompleted event.
need advice
thanks a lot
Don
I resolved this:
in System.Net.Mail I use below:
client.SendCompleted += (s, e) =>
{
Client_SendCompleted(s, e);
...
...
};
private static void Client_SendCompleted(object s, AsyncCompletedEventArgs e)
in Mailkit I use below:
smtp.MessageSent += (sender, args) => Smtp_MessageSent(sender, args, _jo);
_jo is my JObject
private static void Smtp_MessageSent(object sender, MailKit.MessageSentEventArgs e, JObject _jo)
Related
I've defined two AfterThrowing advices to handle exceptions with the same pointcut.
#AfterThrowing(pointcut="...", throwing="ex")
public void method1(Exception ex) {}
#AfterThrowing(pointcut="...", throwing="ex")
public void method2(GatewayException ex) {}
Is there a way for me to prevent the generic method1 being executed if the exception is a GatewayException?
Any ideas greatly appreciated
C
It would be the easiest to check the instance of the exception inside the advice body and return early if it's of the more specific exception type:
#AfterThrowing(pointcut="...", throwing="ex")
public void method1(Exception ex) {
if (ex instanceof GatewayException) {
return;
}
// handle the more generic Exception case
}
#AfterThrowing(pointcut="...", throwing="ex")
public void method2(GatewayException ex) {
// handle the more specific GatewayException
}
I know you expected a solution based on some AspectJ language construct, but the thing is, there's no such construct.
I'm trying to write a C++/CLI forms application that creates a lot of buttons at runtime: I have a vector of strings and for each string a button is being created:
std::vector<std::string> strings;
/*
string being initialized with values from file
*/
for ( std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it ) {
Button ^ button = gcnew Button;
/*
button being customized depending on the string
*/
buttonPannel->Controls->Add(button);
}
Now what I want to do is add an event handler for each button in a way that the string used to customize the button would be passed to handling method.
In c# I would have written something like
button->Click += new EventHandler((sender, args) => button_Click(s, e, *it));
How do I achieve this in C++/CLI?
You could do the exact equivalent of your C# code, but I'd rather make use of an existing property on the Button class to hold the extra data you need.
In this case, the Tag property seems appropriate: its purpose is to hold any extra data you need that is closely associated with the control, so this seems on-point for your string that drives the program logic. (You may need to make it a managed String^ object, rather than a std::string, but that's an easy conversion.)
void Form1::CreateButtons()
{
for (std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it)
{
Button ^ button = gcnew Button;
button->Tag = marshal_as<String^>(*it);
button->Click += gcnew EventHandler(this, &Form1::button_Click);
buttonPanel->Controls->Add(button);
}
}
void Form1::button_Click(Object^ sender, EventArgs^ e)
{
Control^ senderControl = dynamic_cast<Control^>(sender);
String^ heroName = nullptr;
if(senderControl != nullptr)
heroName = dynamic_cast<String^>(senderControl->Tag);
if(heroName == nullptr)
{
// Something went wrong. Bail out.
return;
}
// ...
}
If you really do want to do the equivalent of your C# code: Your C# lambda is doing variable capture on the it variable. We can do variable capture in C++/CLI, it's just a lot more manual.
(Note: Your C# example is capturing the iterator, not the string, not sure if that's what was intended. I wrote this to capture the string object instead.)
ref class EventHandlerStringCapture
{
public:
EventHandlerStringCapture(std::string str,
Action<Object^, EventArgs^, std::string>^ handler)
{
this->str = str;
this->handler = handler;
}
void eventHandler(Object^ sender, EventArgs^ e)
{
this->handler(sender, e, this->str);
}
private:
std::string str;
Func<Object^, EventArgs^, std::string>^ handler;
}
void Form1::CreateButtons()
{
for (std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it)
{
Button ^ button = gcnew Button;
// The variable to capture.
std::string str = *it;
// The actual event handler: a method in the current class.
Action<Object^, EventArgs^, std::string>^ actualHandler =
gcnew Action<Object^, EventArgs^, std::string>(this, &Form1::button_Click);
// Pass both the variable to capture and the
// actual event handler to a helper object.
EventHandlerStringCapture^ ehsc =
gcnew EventHandlerStringCapture(str, actualHandler);
// Grab the two-parameter event handler from the helper object,
// and make that the click handler.
button->Click +=
gcnew EventHandler(ehsc, &EventHandlerStringCapture::eventHandler);
buttonPanel->Controls->Add(button);
}
}
void Form1::button_Click(Object^ sender, EventArgs^ e, std::string heroName)
{
// ...
}
(Note: I'm not at a compiler, so there may be syntax errors.)
Obviously, using an existing property on the button object is simpler, but that's the C++/CLI equivalent to what the C# compiler does behind the scenes.
I have a simple wrapper around a WYSIWYG editor (TinyMCE). I'm using JSNI to call a Java instance method (onClick) from Javascript. However the Java onClick method always gets called on the same Java instance (the last one created), no matter the editor that originated it.
private SimplePanel panel;
private TextArea ta;
private String id;
public TinyMCE(AbstractTinyMCEConfiguration config) {
id = HTMLPanel.createUniqueId();
ta = new TextArea();
ta.getElement().setId(id);
panel = new SimplePanel();
panel.add(ta);
initWidget(panel);
init(config);
}
protected native void init(AbstractTinyMCEConfiguration conf) /*-{
var ins = this;
$wnd.tinyMCE.init({
// General options
mode : conf.#com.chip.tinymce.client.AbstractTinyMCEConfiguration::getMode()(),
setup : function(ed) {
ed.onClick.add(function(ed,e) {
alert(ed.id);
ins.#com.chip.tinymce.client.TinyMCE::onClick(Lcom/google/gwt/dom/client/NativeEvent;)(e);
});
}
});
}-*/;
private void onClick(NativeEvent e) {
GWT.log("onClick " + id);
ClickEvent.fireNativeEvent(e, this);
}
I'm not sure if I can call a Java method from a Javascript funcion that is inside another funcion. Maybe that explains my problem... or maybe I'm missing something. Thanks for your help.
I think TinyMCE has one shared configuration for all editors, and that is the problem here.
It probably does not make much sense to hand the configuration to the constructor if it is shared...
Why not add a static map that maps the id back to the Java instance, something like
// ....
private static Map<String, TinyMCE> idMap = new HashMap<String, TinyMCE>();
public TinyMCE() {
// ...
idMap.put(id, this);
}
// call this from Javascript with (ed.id, e)
private static void onClick(String id, NativeEvent e) {
idMap.get(id).onClick(e);
}
Is there a way to use MVVM Light to handle application events like Closed, Deactivated, Activated, etc?
Thanks to Matt Casto for sending me in the right direction.
Here is the working code:
App.xaml.cs:
private void Application_Activated(object sender, ActivatedEventArgs e)
{
Messenger.Default.Send(new NotificationMessage<AppEvents>(AppEvents.Activated, string.Empty));
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
Messenger.Default.Send(new NotificationMessage<AppEvents>(AppEvents.Deactivated, string.Empty));
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
Messenger.Default.Send(new NotificationMessage<AppEvents>(AppEvents.Closing, string.Empty));
}
ViewModel:
Messenger.Default.Register<NotificationMessage<AppEvents>>(this, n =>
{
switch (n.Content)
{
case AppEvents.Deactivated:
_sessionPersister.Persist(this);
break;
case AppEvents.Activated:
var model = _sessionPersister.Get<TrackViewModel>();
break;
}
});
One thing you could do is handle these events in the App.xaml.cs and have them send a message using the default Messenger instance. Then just have any view models register to receive the message. If you need to cancel the event, use the message with a callback telling the application to cancel.
i have just looked into hooking my application into nhibernate (fluent nhibernate) but i am having a few difficulties...
I have tried to follow what people have done and found this:
public class NHibernateSessionPerRequest : IHttpModule
{
private static readonly ISessionFactory _sessionFactory;
static NHibernateSessionPerRequest()
{
_sessionFactory = CreateSessionFactory();
}
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
}
public static ISession GetCurrentSession()
{
return _sessionFactory.GetCurrentSession();
}
public void Dispose() { }
private static void BeginRequest(object sender, EventArgs e)
{
ISession session = _sessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
private static void EndRequest(object sender, EventArgs e)
{
ISession session = CurrentSessionContext.Unbind(_sessionFactory);
if (session == null) return;
try
{
session.Transaction.Commit();
}
catch (Exception)
{
session.Transaction.Rollback();
}
finally
{
session.Close();
session.Dispose();
}
}
private static ISessionFactory CreateSessionFactory()
{
string connString = "AV8MediaUser";
FluentConfiguration configuration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ShowSql().ConnectionString(
x => x.FromConnectionStringWithKey(connString)))
.ExposeConfiguration(
c => c.SetProperty("current_session_context_class", "web"))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Category>());
return configuration.BuildSessionFactory();
}
}
But when i run it through it seems to connect to the database correctly but it doesnt run a query:
return Session.CreateCriteria<Category>()
.List<Category>();
Am i doing something stupidly wrong?
CreateCriteria expects you to specify a model object name that you'd like to retrieve instances of. You seem to be missing your model object type name. Try something more like this:
List<YourModelObject> results = session.CreateCriteria<YourModelObject>()
.List<YourModelObject>();
To see what's actually being sent to the database consider using Ayende's NHProfiler - it will come in handy later when seeing what your more complex criteria queries or HQL queries actually result in...
Got it... i didnt realise that my mappings werent included in the project for some unknown reason... but included them again and it is all good!
Weird how it didnt throw an error though.