I am trying to load dependencies using Ninject. But NinjectWebCommon is unable to load NinjectModules in the referred assemblies.
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
below is the module I am trying to load
using System;
using Ninject.Modules;
namespace App.Security
{
public class SecurityModule : NinjectModule
{
public override void Load()
{
Bind<IAppAuthenticationManager>().To<AppAuthenticationManager>();
Bind(typeof(IAppUserManager<>)).To(typeof(AppUserManager<>));
Bind<AppUser>().ToSelf();
}
}
}
I am unable to figure out why it can't load the module?
After some head banging session, I figured out that I need to call
kernel.Load<SecurityModule>();
in the RegisterServices method of NinjectWebCommon.
Related
I have a Cross-Platform Xamarin app iOS and wanted to add the nfc-scan functionality.
I followed the link- https://learn.microsoft.com/en-us/xamarin/ios/platform/introduction-to-ios11/corenfc
These have been configured properly-
Info.plist privacy key.
Entitlements.plist entry.
provisioning profile with NFC Tag Reading capability.
I've put all into a new RFIDReader class which is present in a iOS Class Library, and this method gets called from my ViewModel class.
If I run this code, everything looks fine. The scan starts when I press the button on my phone, it shows the blue tick symbol but then it never gets into one of the implemented methods DidDetect, DidInvalidate.
Do you know what the reason could be?
Here's my code-
/// <summary>
/// Class for RFID form control
/// </summary>
public sealed class RFIDReader : UIViewController, IRFIDReader, INFCNdefReaderSessionDelegate
{
/// <summary>
/// The scanning session
/// </summary>
private NFCNdefReaderSession session;
/// <summary>
/// The task completion source
/// </summary>
private TaskCompletionSource<string> tcs;
/// <summary>
/// Gets the handle
/// </summary>
/// <value>The handle</value>
public new IntPtr Handle { get; }
/// <summary>
/// Read the string characters from scanning
/// </summary>
/// <returns>Task status</returns>
public Task<string> ScanCode()
{
if (!NFCNdefReaderSession.ReadingAvailable)
{
//// NFC is not available or disabled
throw new Exception(FormsErrorConstants.NearFieldCommunicationDisabled);
}
this.tcs = new TaskCompletionSource<string>();
this.session = new NFCNdefReaderSession(this, DispatchQueue.CurrentQueue, true);
this.session.BeginSession();
return this.tcs.Task;
}
/// <summary>
/// Called when a tag is successfully read
/// </summary>
/// <param name="session">Session</param>
/// <param name="messages">Messages</param>
public void DidDetect(NFCNdefReaderSession session, NFCNdefMessage[] messages)
{
var bytes = messages[0].Records[0].Payload.Skip(3).ToArray();
var message = Encoding.UTF8.GetString(bytes);
this.tcs.SetResult(message);
}
/// <summary>
/// Called when an error occurs or the 60 second timeout is reached
/// </summary>
/// <param name="session">Session</param>
/// <param name="error">Error</param>
public void DidInvalidate(NFCNdefReaderSession session, NSError error)
{
var readerError = (NFCReaderError)(long)error.Code;
if (readerError != NFCReaderError.ReaderSessionInvalidationErrorFirstNDEFTagRead &&
readerError != NFCReaderError.ReaderSessionInvalidationErrorUserCanceled)
{
// some error handling
}
this.tcs.SetResult(string.Empty);
}
/// <summary>
/// Clean up method
/// </summary>
public new void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Clean up method
/// </summary>
/// <param name="isDisposing">is disposing</param>
private new void Dispose(bool isDisposing)
{
if (isDisposing)
{
// Dispose
this.session.InvalidateSession();
this.session = null;
}
}
}
In my NinjectDependencyresolver I have this:
public NinjectDependencyResolver(IKernel kernelParam)
{
this.kernel = kernelParam;
AddBindings();
}
private void AddBindings()
{
kernel.Bind<IProductsRepository>().To<EFProductRepository>();
}
and then in my controller class I have this:
public class ProductController : Controller
{
private IProductsRepository repository;
public int PageSize = 4;
public ProductController()
{
}
public ProductController(IProductsRepository productRepository)
{
this.repository = productRepository;
}
The problem is that the repository is null
Also If I add a break point to the AddBinsings() method, it doesn't get hit before going to the controller, controller gets hit but AddBindings() does not.
So does it mean it is a problem with my Ninject?
ALSO: I added the parameter less constructor of ProductController after getting this error:
No parameterless constructor defined for this object
I don't think I need that constructor, but if I remove it I get that error.
I would start by removing the constructor to ProductController that has no parameters. This will force ninject to use the constructor with IProductsRepository.
As for the binding part, we have the binding taking place inside the NinjectWebCommon.cs file. Here is our sample:
public static class NinjectWebCommon
{
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof (OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof (NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
Bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel(new VBNinjectModule());
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
BindWebSpecificServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new VBNinjectDependencyResolver(kernel);
return kernel;
}
public static void BindWebSpecificServices(IKernel kernel)
{
kernel.Bind<IUserHelper>()
.To<UserHelper>()
.InRequestScope();
kernel.Bind<IRoleWebService>()
.To<RoleWebService>()
.InRequestScope();
}
Should have also called it in Gloabal.ashx.cs file
I created a simple service with service stack.
namespace BE.Source.Listener.Services
{
public class StatusService : Service
{
private ILog Logger
{
get
{
return LogManager.GetLogger(GetType()); ;
}
}
public object Get(KilnListenerStatusRequest request)
{
var result = new KilnListenerStatusResponse();
result.LastPushRequest = DateTime.Now;
return result;
}
}
}
The service returns a dto named "StatusResult" which has the ResponseSTatus property.
The Request and the result dtos are in the same name space but not in the one the serivce is,
Or is StatusREsult only filled when a error occurs ?
namespace BE.Source.ServiceModel
{
/// <summary>
/// Request for Service Status
/// </summary>
public sealed class StatusRequest : IReturn<StatusResult>
{
}
}
namespace BE.Source.ServiceModel
{
/// <summary>
///
/// </summary>
public sealed class StatusResult
{
/// <summary>
/// Status of the response
/// </summary>
public ResponseStatus ResponseStatus { get; set; } //Automatic exception handling
}
But when firing the get with the jsonservice cleint the property is null.
To the best of my knowledge the ResponseStatus property will be null when no error has occured.
From one of the many tests in the ServiceStack GitHub repo:
[Test, TestCaseSource(typeof(CustomerServiceValidationTests), "ServiceClients")]
public void Post_ValidRequest_succeeds(Func<IServiceClient> factory)
{
var client = factory();
var response = client.Send<CustomersResponse>(validRequest);
Assert.That(response.ResponseStatus, Is.Null);
}
Just a quick question, how do I get the local Bluetooth devices that have already been paired using the Motorola's EMDK 2.4 for an MC75 device? Seems I can get the RemoteDevice list but there is no method to see the local stack and what's been paired already, this way I can read what serial port it has already been assigned and open up a SerialPort object automatically for the user.
The answer is you don't or can't...you instead use the Microsoft Bluetooth. Download this for windows mobile bluetooth on a motorola device...may work on other devices too. You can get from the mobile samples, I found it here on my hard drive...C:\Program Files (x86)\Windows Mobile 6 SDK\Samples\Common\CS\Bluetooth. I added this to my project then all I had to do was this to add all the currently paired devices to a listBox
BluetoothRadio radio = new BluetoothRadio();
listBox1.DataSource = radio.PairedDevices;
listBox1.DisplayMember = "Name";
And then when one was selected you can access it as a BlueTooth device like this:
BluetoothDevice device = listBox1.SelectedItem as BluetoothDevice;
You then start stream by
if (device != null) {
BTConnectionManager.Instance.startThread(
StandardServices.SerialPortServiceGuid,
new ThreadStart(StreamProcessor));
if (BTConnectionManager.Instance.Connect(device)) {
...Do something...
I had to modifiy the StreamProcessor and BTConnectionManager a bit to work for me but here is my version of it without the form references in it.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using Microsoft.WindowsMobile.SharedSource.Bluetooth;
namespace Project2 {
/// <summary>
/// Connection Manager to marshal the data connection and reference the
/// data streams to push/pull data.
/// </summary>
public class BTConnectionManager {
BTConnectionManager() { }
/// <summary>
/// reference the Singleton and make a singleton object out of
/// this since we only want one for now.
/// </summary>
public static BTConnectionManager Instance {
get {
return Nested.instance;
}
}
/// <summary>
/// easiest way to make this a singleton that is thread safe.
/// </summary>
class Nested {
static Nested() { }
internal static readonly BTConnectionManager instance = new BTConnectionManager();
}
/// <summary>
/// The Bluetooth radio.
/// </summary>
private BluetoothRadio radio = new BluetoothRadio();
/// <summary>
/// Guid of the Bluetooth service
/// </summary>
private Guid guid;
/// <summary>
/// Thread function that processes data from the stream.
/// </summary>
private ThreadStart streamProcessor;
/// <summary>
/// The two-way communication stream to the other Bluetooth device.
/// </summary>
private NetworkStream stream;
/// <summary>
/// A BinaryReader on top of this.stream
/// </summary>
private BinaryReader reader;
/// <summary>
/// A BinaryWriter on top of this.stream
/// </summary>
private BinaryWriter writer;
/// <summary>
/// Should we stop the service thread, in preparation for
/// exiting the app?
/// </summary>
private bool exiting = false;
/// <summary>
/// The Bluetooth service.
/// </summary>
private BluetoothService bluetoothService;
/// <summary>
/// A BinaryWriter used to write to the other Bluetooth device.
/// </summary>
public BinaryWriter Writer {
get { return writer; }
}
/// <summary>
/// A BinaryReader used to read from the other Bluetooth device.
/// </summary>
public BinaryReader Reader {
get { return reader; }
}
/// <summary>
/// Gets a value indicating whether a connection is established with
/// the other Bluetooth device.
/// </summary>
public bool Connected {
get { return stream != null; }
}
/// <summary>
/// The two-way communication stream to the other Bluetooth device.
/// </summary>
private NetworkStream Stream {
get { return stream; }
set {
stream = value;
if (stream == null) {
if (writer != null) {
writer.Close();
writer = null;
}
if (reader != null) {
reader.Close();
reader = null;
}
} else {
writer = new BinaryWriter(stream);
reader = new BinaryReader(stream);
}
}
}
/// <summary>
/// Creates a new instance of a ConnectionManager.
/// </summary>
/// <param name="guid">The Bluetooth service guid.</param>
/// <param name="streamProcessor">A callback function that will read and process data from the stream.</param>
public void startThread(Guid guid, ThreadStart dataProcessor) {
this.guid = guid;
this.streamProcessor = dataProcessor;
Thread t = new Thread(new ThreadStart(ServiceThread));
t.Start();
}
/// <summary>
/// The thread that listens for Bluetooth connections, and processes
/// the data read from a connection once established.
/// </summary>
private void ServiceThread() {
bluetoothService = new BluetoothService(this.guid);
while (!exiting) {
if (!bluetoothService.Started) {
bluetoothService.Start();
}
try {
this.Stream = bluetoothService.AcceptConnection();
} catch (System.Net.Sockets.SocketException) {
// bluetoothService.Stop() was called.
// Treat this like a graceful return from AcceptConnection().
}
if (!exiting) {
// Call the streamProcessor to handle the data from the stream.
streamProcessor();
}
}
exiting = false;
}
/// <summary>
/// Force the service thread to exit.
/// </summary>
public void Exit() {
// This will cause us to fall out of the ServiceThread() loop.
exiting = true;
if (!Connected) {
// We must be waiting on AcceptConnection(), so we need to
// force an exception to break out.
bluetoothService.Stop();
}
}
/// <summary>
/// Connect to another Bluetooth device.
/// </summary>
public bool Connect(BluetoothDevice device) {
if (device != null) {
try {
this.Stream = device.Connect(this.guid);
} catch (System.Net.Sockets.SocketException) {
// Couldn't connect.
}
if (this.Stream == null) {
System.Windows.Forms.MessageBox.Show("Could not connect to device " + device.Name);
return false;
} else {
// Forcibly break out of the AcceptConnection in
// ServiceThread(), and continue on to streamProcessor().
bluetoothService.Stop();
return true;
}
}
return false;
}
/// <summary>
/// Disconnect from the other Bluetooth device.
/// </summary>
public void Disconnect() {
Stream = null;
}
internal void Disconnect(BluetoothDevice device) {
Disconnect();
}
}
}
i have a timer job which i want to run only once per day, for the entire farm. How do I
Deploy it in a multiple WFE environment? Do I run the stsadm -o deploysolution command in every WFE, or just the one where I want to run it?
Where should i activate the feature? Should it be activated only from a particular WFE?
What should be the value of the SPJobLockType.
It looks like you need a farm-scoped feature, that installs a service that runs this job. Here is how I did it (using code written by a colleague, to be honest, but he's not in SO).
Create a feature.xml file with a feature event receiver.
<Feature
Id="..."
Title="..."
Description="..."
Scope="Farm"
Version="1.0.0.0"
Hidden="FALSE"
ReceiverAssembly="XXX.FarmService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxx"
ReceiverClass="XXX.FarmService.XXXFarmFeatureEventReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>
Inside the event receiver:
public override void OnFeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPFarm farm = SPFarm.Local;
// Get Service, if it already exists
JobService myService = null; // JobService is a subclass of SPService
foreach (SPService service in farm.Services)
{
if (String.Compare(service.Name, JobService.XXXServiceName, true) == 0)
{
myService = (service as JobService);
break;
}
}
if (cegService == null)
{
// Create service
myService = new JobService(farm);
myService.Update();
// Create service instances
JobServiceInstance myServiceInstance; // JobServiceInstance is a subclas of SPServiceInstance
foreach (SPServer server in farm.Servers)
{
myServiceInstance = new JobServiceInstance(server, myService);
myServiceInstance.Update();
}
}
// Dayly schedule
SPDailySchedule schedule = new SPDailySchedule();
schedule.BeginHour = 1;
schedule.EndHour = 1;
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
// Our own job; JobCheckDocDates is a subclass of SPJobDefinition
JobCheckDocDates newJob = new JobCheckDocDates(cegService, null, SPJobLockType.Job);
newJob.Schedule = schedule;
newJob.Update();
myService.JobDefinitions.Add(newJob);
myService.Update();
}
catch (Exception e)
{
Logger.Error("[" + properties.Feature.Definition.DisplayName + "] Error during feature activation", e);
}
}
This creates a service available on every server in the farm.
Some more details on the subclasses:
public class JobCheckDocDates: Common.BaseJob
{
/// <summary>
/// The job name
/// </summary>
public static string JobName = "XXX job";
/// <summary>
/// Constructor
/// </summary>
public JobCheckDocDates() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="service"></param>
/// <param name="server"></param>
/// <param name="lockType"></param>
public JobCheckDocDates(SPService service, SPServer server, SPJobLockType lockType)
: base(JobName, service, server, lockType) { }
...
and of course the Execute method.
public class JobService : SPService
{
public static string XXXServiceName = "XXX Service";
public override string DisplayName
{
get
{
return XXXServiceName;
}
}
public override string TypeName
{
get
{
return "XXX Service Type";
}
}
/* An empty public constructor required for serialization. */
public JobService() { }
public JobService(SPFarm farm)
: base(XXXServiceName, farm)
{
}
}
public class JobServiceInstance : SPServiceInstance
{
/// <summary>
/// Eos Service Instance Name
/// </summary>
public static string XXXServiceInstanceName = "XXXServiceInstance";
/// <summary>
/// Manage Link
/// </summary>
private SPActionLink _manageLink;
/// <summary>
/// Provision Link
/// </summary>
private SPActionLink _provisionLink;
/// <summary>
/// Unprovision Link
/// </summary>
private SPActionLink _unprovisionLink;
/// <summary>
/// Roles
/// </summary>
private ICollection<string> _roles;
/// <summary>
/// Manage Link
/// </summary>
public override SPActionLink ManageLink
{
get
{
if (_manageLink == null)
{
_manageLink = new SPActionLink(SPActionLinkType.None);
}
return _manageLink;
}
}
/// <summary>
/// Provision Link
/// </summary>
public override SPActionLink ProvisionLink
{
get
{
if (_provisionLink == null)
{
_provisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _provisionLink;
}
}
/// <summary>
/// Unprovision Link
/// </summary>
public override SPActionLink UnprovisionLink
{
get
{
if (_unprovisionLink == null)
{
_unprovisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _unprovisionLink;
}
}
/// <summary>
/// Roles
/// </summary>
public override ICollection<string> Roles
{
get
{
if (_roles == null)
{
_roles = new string[1] { "Custom" };
}
return _roles;
}
}
/// <summary>
/// Empty constructor
/// </summary>
public JobServiceInstance() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="server">The server</param>
/// <param name="service">The Eos service</param>
public JobServiceInstance(SPServer server, JobService service)
: base(XXXServiceInstanceName, server, service)
{
}
Now, in Central Admin, go to Operations / Services on server. Choose the desired server and start the service.
To answer your list of questions:
1. Deploy the solution just once, independently of a WFE.
2. As the feature is farm-scoped, it should be activated in Central Admin.
3. The SPJobLockType is SPJobLockType.Job
This is not exactly what you imagined, but it has the advantage of letting you easily choose where the job is run, even long after you install the feature (e.g. if a server becomes overloaded with other stuff).
The OnFeatureActivated method could be smarter and check for each server if the service exists and add it if needed. But it is simpler to remove the service from every service in OnFeatureDeactivated. So, if you add new servers, deactivate then reactivate the feature.