Can't get Ninject.Extensions.Interception working - ninject

I've been trying for ages to figure this our. when i try to bind my class with an interceptor i'm getting the following exception on the line
Kernel.Bind<MyClass>().ToSelf().Intercept().With<ILoggerAspect>();
Error loading Ninject component IAdviceFactory. No such component has been registered in the kernel's component container
I've tried with and without LoadExtensions, With about with using a Module to set up my bindings and my last attempt looks like this
internal class AppConfiguration
{
internal AppConfiguration( )
{
var settings = new NinjectSettings() { LoadExtensions = false };
Kernel = new StandardKernel(settings);
Load();
}
internal StandardKernel Kernel { get; set; }
public static AppConfiguration Instance
{
get { return _instance ?? (_instance = new AppConfiguration()); }
}
private static AppConfiguration _instance;
private void Load()
{
Kernel.Bind<ILoggerAspect>().To<Log4NetAspect>().InSingletonScope();
Kernel.Bind<MyClass>().ToSelf().Intercept().With<ILoggerAspect>();
}
internal static StandardKernel Resolver()
{
return Instance.Kernel;
}
}
My Logger Attribute looks like this
public class LogAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Context.Kernel.Get<ILoggerAspect>();
}
}
And my interceptor like this
public class Log4NetAspect : SimpleInterceptor, ILoggerAspect
{
protected override void BeforeInvoke(IInvocation invocation)
{
Debug.WriteLine("Running " + invocation.ReturnValue);
base.BeforeInvoke(invocation);
}
public new void Intercept(IInvocation invocation)
{
try
{
base.Intercept(invocation);
}
catch (Exception e)
{
Debug.WriteLine("Exception: " + e.Message);
}
}
protected override void AfterInvoke(IInvocation invocation)
{
Debug.WriteLine("After Method");
base.AfterInvoke(invocation);
}
}

Most likely you didn't deploy Ninject.Extensions.Interception.DynamicProxy or Ninject.Extensions.Interception.Linfu alongside your application [and Ninject.Extensions.Interception]. You have to pick exactly one of them.
With the code as you have it right now (LoadExtensions=false) it will fail to pick up the specific interception library - you should remove that and the normal extensions loading should wire the extension into the Kernel on creation for the interception bits to pick it up.

In addition to Remo Gloor's answer which pointed me toward adding the nuget package for Ninject.Extensions.Interception.DynamicProxy, I kept getting the same exception as the OP, until I manually loaded a DynamicProxyModule - the FuncModule is manually loaded as well, to work around a similar error involving the factory extension:
_kernel = new StandardKernel(
new NinjectSettings{LoadExtensions = true},
new FuncModule(),
new DynamicProxyModule()); // <~ this is what fixed it

Related

React Native how to use Braintree PayPal Value

I use react-native to develop an app, and I need to connect to braintree (paypal value). The official provides 3 kinds of sdk, js, android, and ios. I try to connect to the native android library, but it doesn't seem to have any effect.After calling the native method in ReactNative, only "react-native-test" is output (No error is reported, and there is no change on the interface. It seems that it should jump to PayPal authorization to be normal). I'm not sure if it's my problem . I also tried to use js library in react-native, but after importing a certain method, my program doesn't start. Or can I only do it in webView? Has anyone connected with PayPal value? Can you give me some advice? Thanks.
Here is the documentation I refer to.
Below is my android codeļ¼š
public class BraintreeValueModule extends ReactContextBaseJavaModule implements PayPalListener {
private static ReactApplicationContext reactContext;
private Callback successCallback;
private Callback errorCallback;
private BraintreeClient braintreeClient;
private PayPalClient payPalClient;
public BraintreeValueModule(ReactApplicationContext context) {
super(context);
reactContext = context;
}
#NonNull
#Override
public String getName() {
return "BraintreeValueModule";
}
#ReactMethod
public void test(){
System.out.println("react-native-test");
braintreeClient = new BraintreeClient(reactContext.getApplicationContext(), "sandbox_ykbznr4s_ctmssyj6wz2qcj2g");
FragmentActivity activity = (FragmentActivity) getCurrentActivity();
activity.runOnUiThread(new MyRunnable(activity,braintreeClient));
//The following writing method will report an error: Method addObserver must be called on the main thread
//if(activity != null){
// payPalClient = new PayPalClient(activity, braintreeClient);
// payPalClient.setListener(this);
//}
}
#Override
public void onPayPalSuccess(#NonNull PayPalAccountNonce payPalAccountNonce) {
successCallback.invoke(payPalAccountNonce.toString());
}
#Override
public void onPayPalFailure(#NonNull Exception error) {
if (error instanceof UserCanceledException) {
// user canceled
errorCallback.invoke("use canceled");
} else {
// handle error
errorCallback.invoke("error");
}
}
}
public class MyRunnable implements Runnable, PayPalListener {
private BraintreeClient braintreeClient;
private PayPalClient payPalClient;
private FragmentActivity activity;
MyRunnable(FragmentActivity activity,BraintreeClient braintreeClient){
this.activity = activity;
this.braintreeClient = braintreeClient;
}
#Override
public void run() {
if(activity != null){
payPalClient = new PayPalClient(activity, braintreeClient);
payPalClient.setListener(this);
}
}
#Override
public void onPayPalSuccess(#NonNull PayPalAccountNonce payPalAccountNonce) {
System.out.println(payPalAccountNonce.getString());
}
#Override
public void onPayPalFailure(#NonNull Exception error) {
if (error instanceof UserCanceledException) {
// user canceled
System.out.println("use canceled");
} else {
// handle error
System.out.println("error");
}
}
}
I believe you might have missed out the following few lines:
PayPalVaultRequest request = new PayPalVaultRequest();
request.setBillingAgreementDescription("Your agreement description");
payPalClient.tokenizePayPalAccount(getCurrentActivity(), request);
However, I believe it might still not work as I had similar problem when I was trying to integrate the drop-in.
I'm afraid that you'll need to initialise your clients (in your case, BraintreeClient and PaypalClient) in the onCreate method of your MainActivity.
And then try to call a reference to the client (either by SharedPreference or static variable) in your module to launch the drop in.
Pretty sure it's similar issue to your case.
This only applies to the v4 library.
Read more on this thread:
https://github.com/braintree/braintree-android-drop-in/issues/374#issuecomment-1345929549

MockingKernel and Received throws an NotASubstituteException

I'm using NSubstituteMockingKernel in order to build all my dependencies of my library classes. I've been struggling to solve a trouble for a week and I'm really exhausted. I need some help.
This is my class:
class Core : ICoreService, ICore {
private ICoreConfiguration configuration;
Core(ICoreconfiguration configuration) {
this.configuration = configuration;
}
override ICoreService.ParentMethod() { //ICoreService implementation
foreach (Item item in this.configuration.Items)
this.ChildMethod();
}
virtual ChildMethod() {
//do something
}
}
ICoreService is:
interface ICoreService {
void ParentMethod();
}
ICore is:
interface ICore {
ICoreConfiguration Configuration { get; }
}
ICoreConfiguration is:
interface ICoreConfiguration {
IEnumerable<Item> Items { get; }
}
My test is:
[TestFixture]
public class UsersManagementTests
{
private readonly NSubstituteMockingKernel IoCKernel;
public UsersManagementTests()
{
this.IoCKernel = new NSubstituteMockingKernel();
}
[SetUp]
public void SetUp()
{
this.IoCKernel.Reset();
}
[Test(Description = "Configured Users are well loaded on Kernel")]
public void InitializationWithUsersTest()
{
//Setup Data
Item item = Item.Create("item1");
IEnumerable<Item> items = new List<Item>() { item };
//Setup Mocks
this.IoCKernel
.Get<ICoreConfiguration>()
.Items
.Returns(items);
Core core = this.IoCKernel.Get<Core>();
//Act
kernel.ParentMethod();
//Assert
IEnumerable<NSubstitute.Core.ICall> calls = kernel.ReceivedCalls(); // ((((((1))))))
kernel.Received(1).ChildMethod(); // ((((((2))))))
}
}
When ((((((1)))))) or ((((((2)))))) are reached, I'm getting this NSubstitute.Exceptions.NotASubstituteException exception message now on last line:
NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods.
As you can see I'm trying to test ChildMethod method is reached once at least. ChildMethod must be called according to my Core.Kernel implementation.
I will really appreciate some help.
Thanks.

Pass data from android service to ContentPage in Xamarin Form based application

I am having one Application based on XamarinForms.
One background service I have created in Android project and that service would like to send data to ContentPage(which is in PCL) which is displayed to user.
How could I pass data to ContentPage(From xx.Droid project to PCL)?
One solution is:
To Create class in PCL with static variable(e.g. var TEMP_VAR), which will be accessed from xxx.Droid project.
Update value of that static variable(TEMP_VAR) from the service class from the xxx.Droid project.
Need to create Notifier on that static variable(TEMP_VAR)
Update the content page using MessageCenter Mechanism if require.
If there is any better solution, could you please provide me?
This can be achieved using the concept of C#
Dependency service
Event
Need to have 4 classes for such an implementation:
Interface in PCL(e.g. CurrentLocationService.cs) with event handlers defined in it.
namespace NAMESPACE
{
public interface CurrentLocationService
{
void start();
event EventHandler<PositionEventArgs> positionChanged;
}
}
Implementation of interface of PCL in xxx.Droid project (e.g. CurrentLocationService_Android.cs) using Dependency service
class CurrentLocationService_Android : CurrentLocationService
{
public static CurrentLocationService_Android mySelf;
public event EventHandler<PositionEventArgs> positionChanged;
public void start()
{
mySelf = this;
Forms.Context.StartService(new Intent(Forms.Context, typeof(MyService)));
}
public void receivedNewPosition(CustomPosition pos)
{
positionChanged(this, new PositionEventArgs(pos));
}
}
ContentPage in PCL - which will have object of implementation of interface.
Object can be obtained by
public CurrentLocationService LocationService
{
get
{
if(currentLocationService == null)
{
currentLocationService = DependencyService.Get<CurrentLocationService>();
currentLocationService.positionChanged += OnPositionChange;
}
return currentLocationService;
}
}
private void OnPositionChange(object sender, PositionEventArgs e)
{
Debug.WriteLine("Got the update in ContentPage from service ");
}
Background service in xxx.Droid project. This service will have reference of implementation of dependency service CurrentLocationService.cs
[Service]
public class MyService : Service
{
public string TAG = "MyService";
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug(TAG, TAG + " started");
doWork();
return StartCommandResult.Sticky;
}
public void doWork()
{
var t = new Thread(
() =>
{
Log.Debug(TAG, "Doing work");
Thread.Sleep(10000);
Log.Debug(TAG, "Work completed");
if(CurrentLocationService_Android.mySelf != null)
{
CustomPosition pos = new CustomPosition();
pos.update = "Finally value is updated";
CurrentLocationService_Android.mySelf.receivedNewPosition(pos);
}
StopSelf();
});
t.Start();
}
}
Note : PositionEventArgs class need to be created as per usage to pass on data between service and ContentPage.
This works for me like charm.
Hope so this would be helpful to you.

Instantiate using Windsor's factory

Below's code is working fine, and successfully create an instance for class DummyComponnent.
But the problem arises when i had changed the factory method name CreatDummyComponnent()
to GetDummyComponnent() or anything else except Creat as the beginning of method name, say AnyThingComponent throws an exception. is there any specify naming rule for factory methods ?
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace AsFactoryImplementation
{
public interface IDummyComponnentFactory
{
IDummyComponnent CreatDummyComponnent();
// void Relese(IDummyComponnent factory);
}
public interface IDummyComponnent
{
void Show();
}
public class DummyComponnent:IDummyComponnent
{
public DummyComponnent()
{
Console.WriteLine("we are working here");
}
public void Show()
{
Console.WriteLine("just testing this for better performance");
}
}
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IDummyComponnent>().ImplementedBy<DummyComponnent>().Named("FirstConnection"),
Component.For<IDummyComponnentFactory>().AsFactory());
var val = container.Resolve<IDummyComponnentFactory>();
var iDummy = val.CreatDummyComponnent();
iDummy.Show();
Console.WriteLine("OK its done ");
Console.ReadLine();
}
}
}
You should be able to use anything for starting the method names on the Factory, except for starting with Get.
If you start with Get it will try to resolve the component by name instead of by interface.
So what would work in your example is:
var iDummy = val.GetFirstConnection();
Good luck,
Marwijn.

CodeCampServer don't input any logging from NHibernate?

Are you ever succeed input NHibernate logging using CodeCampServer architecture?
I read this and I did everything that I can. Maybe there is know problem in this architecture.
I using Infrastructure.NHibernate.DataAccess.Bases.Logger.EnsureInitialized();
to initialize log4net. here the code:
public class DependencyRegistrar
{
private static bool _dependenciesRegistered;
private static void RegisterDependencies()
{
ObjectFactory.Initialize(x => x.Scan(y =>
{
y.AssemblyContainingType<DependencyRegistry>();
y.AssemblyContainingType<NaakRegistry>();
y.LookForRegistries();
y.AddAllTypesOf<IRequiresConfigurationOnStartup>();
}));
new InitiailizeDefaultFactories().Configure();
}
private static readonly object sync = new object();
internal void ConfigureOnStartup()
{
Infrastructure.NHibernate.DataAccess.Bases.Logger.EnsureInitialized();
RegisterDependencies();
var dependenciesToInitialized = ObjectFactory.GetAllInstances<IRequiresConfigurationOnStartup>();
foreach (var dependency in dependenciesToInitialized)
{
dependency.Configure();
}
}
public static T Resolve<T>()
{
return ObjectFactory.GetInstance<T>();
}
public static object Resolve(Type modelType)
{
return ObjectFactory.GetInstance(modelType);
}
public static bool Registered(Type type)
{
EnsureDependenciesRegistered();
return ObjectFactory.GetInstance(type) != null;
}
public static void EnsureDependenciesRegistered()
{
if (!_dependenciesRegistered)
{
lock (sync)
{
if (!_dependenciesRegistered)
{
RegisterDependencies();
_dependenciesRegistered = true;
}
}
}
}
}
And I see the logging files, I can't delete them when the app run, so I know they are generated. in addition, when I log for test, the log are input. For example, this code do input log.
Bases.Logger.Debug(this, "Debug test!")
So, do CodeCampServer have a architecture problem with log4net?
The post looks correct to me.
Are you sure you added the necessary assembly level attribute?
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
If this won't work maybe you should try:
log4net.Config.XmlConfigurator.Configure();
for example in your Application_Start of Global.asax.
If this won't work please post your example code.
Accidentally found solution by replacing the reference forlog4net.dll to the on that come with NHibernate bins, instead the own log4net.
Wired, but I have logs... :)