I have an abstract class like
public abstract class EventHandler<T> {
public <T> void preProcess(Message<T> message) {
// do some pre-processing with the Message
}
protected abstract void handleEvent(Message<T> message) throws Exception;
public <T> void postProcess(Message<T> message) {
// do some post-processing with the Message
}
}
There are concrete classes which are extending from this Class.
I want to be able to invoke the preProcess() and postProcess() methods in the Abstract class using an #Around aspect when the handleEvent method is invoked on the concrete class.
I am trying to define the aspect like below
#Aspect
#Configuration
public class SomeAspect {
#Around(value = "execution(* com.handler.EventHandler+.handleEvent(..)))")
public void around(ProceedingJoinPoint proceedingJoinPoint) {
1. invoke preProcess
2. invoke the join point
3. invoke postProcess
}
}
How do i achieve what i am looking for?
Update
#Aspect
#Component
public class SomeAspect {
private Logger logger = LoggerFactory.getLogger(TenantAspect.class);
#Around(value = "execution(* com.handler.EventHandler+.handleEvent(..))) && within(com.handler..*) && this(eventHandler) && args(message))")
public void around(ProceedingJoinPoint proceedingJoinPoint, EventHandler<Object> eventHandler, Message<Object> message) {
}
}
Tried the above and compiler gives Unbound Pointcut Parameter for eventHandler and message
Following Aspect can do the same.
Explanation
execution(* com.handler.EventHandler+.handleEvent(..)) - execution of a method named handleEvent which is in a subtype of EventHandler
Designators
within(com.handler..*) - A scoping desginator to advice classes within the given package
Passing parameters to advice
this(eventHandler) - the object executing the method. target() may also be used
args(message) - argument passed at runtime
Notes
An aspect be better annotated with #Component and #Configuration be used for configurations.
within added to narrow the scope to advice.Please modify as needed
#Aspect
#Component
public class EventHandlerAspect {
#Around(value = "execution(* com.handler.EventHandler+.handleEvent(..)) "
+ "&& within(com.handler..*) "
+ "&& this(eventHandler) "
+ "&& args(message))")
public Object around(ProceedingJoinPoint proceedingJoinPoint,
EventHandler<Object> eventHandler,
Message<Object> message) throws Throwable {
Object obj = null;
// 1. invoke preProcess
eventHandler.preProcess(message);
try {
// 2. invoke the join point
obj = proceedingJoinPoint.proceed();
} finally {
// 3. invoke postProcess
eventHandler.postProcess(message);
}
return obj;
}
}
Hope this helps.
You can get the target object directly from the proceedingJoinPoint as follows:
((TestClass<Integer>) proceedingJoinPoint.getTarget()).preProcess(message);
//or
((TestClass<Object>) proceedingJoinPoint.getTarget()).preProcess(message);
You would need to know the generic's instantiation type and have a matching message object of the same type.
If the message is in the arguments of the intercepted function call you can get them as follows:
Object[] methodArguments = proceedingJoinPoint.getArgs();
Message<Integer> message = (Message<Integer>) methodArguments[0];
If message is the first argument, it will be in methodArguments[0]
Related
I am pretty new to Dagger and finding the component body a bit difficult to understand,having 2 specific questions related to the component implementation:
1)
#Singleton
#Component(modules = { UserModule.class, BackEndServiceModule.class })
public interface MyComponent {
BackendService provideBackendService();// Line 1
void inject(Main main); // Line 2
}
What is the purpose of Line 2? also will an instance of backendService be created even if line 1 is removed?
and also in the below code where the implementation of the above interface is generated , what does the component.inject(this) actually do?
public class Main {
#Inject
BackendService backendService; //
private MyComponent component;
private Main() {
component = DaggerMyComponent.builder().build();
component.inject(this);
}
private void callServer() {
boolean callServer = backendService.callServer();
if (callServer) {
System.out.println("Server call was successful. ");
} else {
System.out.println("Server call failed. ");
}
}
and also why has the backendservice not obtained using component.provideBackendService()
What is the purpose of void inject(Main main);?
It lets you perform field injection on concrete class Main, assuming that Main is a class that cannot be created by Dagger
where the implementation of the above interface is generated , what does the component.inject(this) actually do?
It uses MemberInjectors to inject the package-protected or public fields marked with #Inject. You can see the implementation of inject(Main) method in DaggerMyComponent class.
Of course, if possible it is better to make it so that:
1.) Main does not instantiate/know about its own injector
2.) Main is created by the Dagger component and #Inject constructor is used
#Singleton
public class Main {
private final BackendService backendService;
#Inject
Main(BackendService backendService) {
this.backendService = backendService;
}
}
I had following code
public interface IFoo
{
void Execute();
}
public abstract class FooBar: IFoo
{
public void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
and following test case to test the Execute() method
[Fact]
public void When_execute_method_called_Expect_executionTime_is_set()
{
var sutMethod = A.Fake<FooBar>();
A.CallTo(sutMethod).
Where(x => x.Method.Name == "OnExecute").
Invokes(x => Thread.Sleep(100)));
sutMethod.Execute();
Assert.NotEqual(0, sutMethod.Result.ExecutionTime.Ticks);
}
sutMethod.Execute(); call would go to FooBar.Execute()
later I decided to make the interface into an abstract class
public abstract class IFoo
{
public abstract void Execute();
}
public abstract class FooBar:IFoo
{
public override void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
Now sutMethod.Execute(); call does not invoke FooBar.Execute()
I thought FakeItEasy would handles interface and abstract classes as equal.What am I missing?
Update
# Blair Conrad provided the reasoning for the behaviour
Is it possible to make minimal changes to the test case to get the original behaviour back?
thanks
The difference is due to the overrideability of the method Execute on FooBar.
FakeItEasy can only override virtual members, abstract members, or interface members.
In your original example, when IFooBar is an interface and FooBar implements it, Execute is a concrete method. It's not virtual, nor is it abstract. Thus FakeItEasy can't intercept calls to it, and the original method is executed.
Once you change IFooBar to an abstract class, you have an abstract IFooBar.Execute, which you override in FooBar. As such, FooBar.Execute is now virtual and can be intercepted by FakeItEasy. Which it does, so your implementation is not called.
Following addition help solve the issue
A.CallTo(() => sutMethod.Execute()).CallsBaseMethod();
This calls the virtual method Executeof FooBar
I have the following class:
public class MyClass {
#Inject
private MyAnotherClass myAnotherClass;
public MyClass() {
//Perform operations on myAnotherClass.
}
}
I need to do some things in constructor which require an instance of myAnotherClass. Unfortunately myAnotherClass is injected after code in constructor is ran, which means I am performing operations on null...
I could of course instantiate it the classic way (MyAnotherClass myAnotherClass = new MyAnotherClass()) directly in constructor, but I don't think it is the right thing to do in this situation.
What solutions would you suggest to solve this problem?
Best option:
public class MyClass {
private final MyAnotherClass myAnotherClass;
public MyClass(MyAnotherClass other) {
this.myAnotherClass = other;
// And so forth
}
}
T5-IoC will then use constructor injection so there's no need to 'new' up MyClass yourself. See Defining Tapestry IOC Services for more info.
Alternatively:
public class MyClass {
#Inject
private MyAnotherClass myAnotherClass;
#PostInjection
public void setupUsingOther() {
// Called last, after fields are injected
}
}
i was recently digging on new partial methods in c#3.0, i understood the use of partial class, that it could be chunked into multiple file one contain the definition and other declaration, but i wanted to know,i created a partial class like below:
in class1.cs
partial class A
{
partial void Method();
}
in class2.cs
partial class A
{
partial void Method()
{
Console.WriteLine("Hello World");
}
}
now in class3.cs
class MainClass
{
static void Main()
{
A obj = new A();
obj.Method(); //Here i cannot call the "Method" method.
}
}
then whats the use of creating partial method, i read on MSDN that, at runtime, compiler compiles the class into one, in that case compiler should be getting the "Method" method implementation also, then why it dont allow me to call the "Method" method in the main method, can anyone correct me if i am wrong, and tell me why i am unable to call this partial method in main.
From MSDN
No access modifiers or attributes are allowed. Partial methods are
implicitly private.
It's a private method, so you can't call it from main.
You can call a partial method inside the constructor where the method is defined.
For example
public partial class classA
{
partial void mymethod();
}
public partial class classA
{
partial void mymethod()
{
Console.WriteLine("Invoking partial method");
}
public ClassA()
{
mymethod();
}
}
public class MainClass
{
static void Main()
{
ClassA ca=new ClassA();
}
}
That's it..now execute your code and see the result..
OutPut
Invoking partial method
Yes, we can't call it from Main(). Problem is not Partial method problem is method without specifier in a class is Private and private method can be called inside the class only.
Try creating a new public method in Partial class:
partial class A
{
partial void Method();
}
partial class A
{
partial void Method()
{
Console.WriteLine("Hello World");
}
public void Study()
{
Console.WriteLine("I am studying");
Method();
}
}
class MainClass
{
static void Main()
{
A obj = new A();
obj.Study();
}
}
I have the following interface:
public interface ILogger
{
void Debug(string message, params object[] values);
void Info(string message, params object[] values);
void Warn(string message, params object[] values);
void Error(string message, params object[] values);
void Fatal(string message, params object[] values);
}
and the following implementation:
public class Log4netLogger : ILogger
{
private ILog _log;
public Log4netLogger(Type type)
{
_log = LogManager.GetLogger(type);
}
public void Debug(string message, params object[] values)
{
_log.DebugFormat(message, values);
}
// other logging methods here...
}
My idea was to use structuremap to instantiate the Log4netLogger class with using the Type of the class that did the logging. However, I can't for the life of me figure out how to pass the type of the calling class to structuremap so that it can be passed to the constructor of the logging implementation. Any advice on how to do that (or a better way) would be most appreciated.
We use a similar ILogger wrapper around log4net and typically use constructor injection. We use an interceptor as a factory method responsible for creating the Logger. Here is our typical registry for logging setup.
public class CommonsRegistry : Registry
{
public CommonsRegistry()
{
For<ILogger>()
.AlwaysUnique()
.TheDefault.Is.ConstructedBy(s =>
{
if (s.ParentType == null)
return new Log4NetLogger(s.BuildStack.Current.ConcreteType);
return new Log4NetLogger(s.ParentType);
});
var applicationPath = Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location);
var configFile = new FileInfo(Path.Combine(applicationPath, "log4net.config"));
XmlConfigurator.ConfigureAndWatch(configFile);
}
}
The parent type null check is necessary when there are dependencies on concrete types.
The rest is optional log4net setup stuff.
One thing I do like about this setup is the ability to use a null loggers for unit testing.
If the type parameter is context-specific, I don't think this is going to work as shown. If you need to pass something context specific in the constructor, you are likely going to have to create a factory interface and implementation that returns an instance of the ILogger:
public interface ILoggerFactory
{
ILogger Create(Type type);
}
public class LoggerFactory : ILoggerFactory
{
public ILogger Create(Type type)
{
return new Log4netLogger(type);
}
}
It might be possible to bootstrap StructureMap to supply the instance you want based on the type, but that assumes a limited number of types that you know in advance.
I really need to get out of the habit of answering my own question, but for those who run across it, here's the answer.
return ObjectFactory.With(type).GetInstance<T>();
I actually have a wrapper to structuremap (to avoid exposing the structuremap dependency to my app) that looks like the following:
public static class ServiceManager
{
public static T Get<T>()
{
return ObjectFactory.GetInstance<T>();
}
public static T Get<T>(Type type)
{
return ObjectFactory.With(type).GetInstance<T>();
}
}
Any time in the code I need a logger, I call the following:
ServiceManager.Get<ILogger>(GetType()).Info("Logging page view...");