Passing parameter to interfaced class in ninject - c#

I have a class to hold session like this
public class SessionService : ISession
{
public HttpContext Context { get; set; }
public SessionService(HttpContext context)
{
this.Context = context;
}
}
I want to be able to inject the session object in various places in my MVC3 app.
I have this interface
interface ISession
{
HttpContext Context { get; set; }
}
I am using ninject to bind the session class to the interface like this
private void RegisterDependencyResolver()
{
var kernel = new StandardKernel();
kernel.Bind<ISession>().To<SessionService>();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
My problem is how to pass the Httpcontext parameter into the SessionService constructor.
Any pointers most appreciated.
Thanks

Wherever you are setting up your dependencies:
kernel.Bind<HttpContext>().ToMethod(c => HttpContext.Current);
I have a bootstrapper class that does this with a RegisterServices method:
public static class NinjectMVC3
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
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();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<HttpContext>().ToMethod(c => HttpContext.Current);
}
}

Related

Hooking Unity Interception to a method with no parameters

I am working on a proof of concept for using Unity and I am having issues with my interceptor being called. I am using policy injection.
so here is some code
setting up unity:
private void ApplyCrossCuttingConcerns(UnityContainer container)
{
container.AddNewExtension<Interception>();
container.RegisterType<IContact, Contact>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
container.Configure<Interception>()
.AddPolicy("extensionPolicy")
.AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(typeof(Contact).ToString()))
.AddMatchingRule<MethodSignatureMatchingRule>(new InjectionConstructor("Save",new [] {""},true))
.AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
}
my contact class that inherites from BussinessObject where the method in question lives
public class Contact : BussinessObject, IContact
{...}
public abstract class BussinessObject
{
#region Local Vars
protected readonly IRepository _repository;
protected bool isNew;
#endregion Local Vars
#region Properties
/// <summary>
/// Gets or sets a value indicating whether this instance is new.
/// </summary>
/// <value>
/// <see langword="true" /> if this instance is new; otherwise, <see langword="false" />.
/// </value>
internal bool IsNew { get { return (isNew); } set { isNew = value; } }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="BussinessObject"/> class.
/// </summary>
/// <param name="repository">The repository.</param>
public BussinessObject(IRepository repository)
{
if (repository.IsEmpty())
{
throw new Exception("The repository is a maditory parameter for a bussiness object");
}
_repository = repository;
}
#endregion Constructors
#region Methods
#region public
/// <summary>
/// Saves this instance.
/// </summary>
public virtual void Save()
{
Validate();
SetIdenity();
if (isNew)
{
Insert();
}
else
{
Update();
}
isNew = false;
}
/// <summary>
/// Permantlies the remove from system.
/// </summary>
/// <param name="ID">The identifier.</param>
public abstract void PermantlyRemoveFromSystem(Guid id);
#endregion public
#region Internal
/// <summary>
/// Sets the idenity.
/// </summary>
internal abstract void SetIdenity();
#endregion Internal
#region protected
/// <summary>
/// Commons the initialize.
/// </summary>
protected virtual void CommonInit()
{
isNew = false;
}
/// <summary>
/// Inserts this instance.
/// </summary>
protected abstract void Insert();
/// <summary>
/// Updates this instance.
/// </summary>
protected abstract void Update();
/// <summary>
/// Validates this instance.
/// </summary>
protected abstract void Validate();
#endregion protected
#endregion
}
Now the IContact
public interface IContact : DTO.IContact
{
void Save();
void Delete();
#region Phone Number Manipulation
bool SetDefaultNumber(PhoneNumber phNum);
PhoneNumber GetDefaultNumber();
bool HasDefaultNumber();
PhoneNumber[] GetPhoneNumbers();
PhoneNumber[] GetPhoneNumbers(bool includeDeleted);
void AddPhoneNumber(PhoneNumber phToAdd);
bool RemovePhoneNumber(PhoneNumber phToRemove);
#endregion
#region Email Address Manipulation
bool SetDefaultEMailAddress(EmailAddress emAdd);
bool HasDefaultEmailAddress();
EmailAddress[] GetAllEmailAddresses();
EmailAddress[] GetAllEmailAddresses(bool includeDeleted);
EmailAddress AddEmailAddress(string addressToAdd);
EmailAddress GetDefaultEMailAddress();
#endregion
#region Snailmail Address Manipulation
bool SetDefaultAddress(SnailMailAddress ad);
SnailMailAddress GetDefaultAddress();
bool HasDefaultAddress();
SnailMailAddress[] GetAllAddresses();
SnailMailAddress[] GetAllAddresses(bool includeDeleted);
void AddAddress(SnailMailAddress adToAdd);
bool RemoveAddress(SnailMailAddress adToRemove);
#endregion
}
and finally the extensionHandler
public class ExtensionHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
//going to do our work before we pass on to the next item in the pipeline
SomeFunctionality handlerFunctionality = new SomeFunctionality();
handlerFunctionality.PreformWork();
//pass on to the next item in the pipeline
var result = getNext().Invoke(input, getNext);
//we can put post processing logic in here
return result;
}
I setup a test to resolve the contact object and then set so data on it and called the save method. I have a break point at the top of the invoke method in the ExtensionHandler but I never get there. I think the issue with the way I configuring the MethodSignatureMatchingRule but I have not yet to find documentation on the net showing an example of interception being configured to a method with no parameters.
Any help would be appreaiated
so after some more experimentation I found the answer
This issue was in the matching rules
both rules where incorrect the correct code is as follows:
private void ApplyCrossCuttingConcerns(UnityContainer container)
{
container.AddNewExtension<Interception>();
container.RegisterType<IContact, Contact>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
container.Configure<Interception>()
.AddPolicy("extensionPolicy")
.AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(new InjectionParameter(typeof(IContact))))
.AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor(new InjectionParameter("Save")))
.AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
}

Disposal of AsyncLazy, what is the right (easy to use and non-leaky) way?

I'm using a specialization of Stephen Cleary's AsyncLazy implementation, from his blog.
/// <summary>
/// Provides support for asynchronous lazy initialization.
/// This type is fully thread-safe.
/// </summary>
/// <typeparam name="T">
/// The type of object that is being asynchronously initialized.
/// </typeparam>
public sealed class AsyncLazy<T>
{
/// <summary>
/// The underlying lazy task.
/// </summary>
private readonly Lazy<Task<T>> instance;
/// <summary>
/// Initializes a new instance of the
/// <see cref="AsyncLazy<T>"/> class.
/// </summary>
/// <param name="factory">
/// The delegate that is invoked on a background thread to produce
/// the value when it is needed.
/// </param>
/// <param name="start">
/// If <c>true</c> commence initialization immediately.
/// </param>
public AsyncLazy(Func<T> factory, bool start = false)
{
this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
if (start)
{
this.Start();
}
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="AsyncLazy<T>"/> class.
/// </summary>
/// <param name="factory">
/// The asynchronous delegate that is invoked on a background
/// thread to produce the value when it is needed.
/// </param>
/// <param name="start">
/// If <c>true</c> commence initialization immediately.
/// </param>
public AsyncLazy(Func<Task<T>> factory, bool start = false)
{
this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
if (start)
{
this.Start();
}
}
/// <summary>
/// Asynchronous infrastructure support.
/// This method permits instances of
/// <see cref="AsyncLazy<T>"/> to be await'ed.
/// </summary>
public TaskAwaiter<T> GetAwaiter()
{
return this.instance.Value.GetAwaiter();
}
/// <summary>
/// Starts the asynchronous initialization,
/// if it has not already started.
/// </summary>
public void Start()
{
var unused = this.instance.Value;
}
}
This is great code and I really appreciate how easy it is to use. i.e.
class SomeClass
{
private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
() => new Thing());
void SomeMethod()
{
var thing = await theThing;
// ...
}
}
Now my question,
Suppose that SomeClass inherits from a class that implements IDisposable and that Thing implements IDisposable. We'd have skeleton implementation like this,
class SomeClass : SomeDisposableBase
{
private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
() => new Thing());
protected override void Dispose(bool disposing)
{
if (disposing)
{
// What do I do with theThing?
}
base.Dispose(disposing);
}
}
So, what do I do with theThing in the Dispose override? Should I extend AsyncLazy<T> to have a new property?
// ...
public bool IsStarted
{
get
{
return this.instance.IsValueCreated;
}
}
// ...
Should I change AsyncLazy<T> to implement IDisposable?
Have I misunderstood and I don't need to worry?
Should I do something else?
Stephen Toub's version of this class inherits from Lazy<Task<T>>, so you get the IsValueCreated property automatically.
Alternatively, you could expose the IsValueCreated property from the private field:
public sealed class AsyncLazy<T>
{
private readonly Lazy<Task<T>> instance;
...
public bool IsValueCreated
{
get { return instance.IsValueCreated; }
}
}
For consistency with the built-in Lazy<T> type, I'd avoid renaming the property to IsStarted.
You can use a bool inside the AsyncLazy<T> initialization to know if theThing has been initialized
class SomeClass : SomeDisposableBase
{
public SomeClass()
{
theThing = new AsyncLazy<Thing>(() =>
{
_isInitialized = true;
return new Thing();
}
}
private bool _isInitialized;
private readonly AsyncLazy<Thing> theThing;
protected override void Dispose(bool disposing)
{
if (disposing && _isInitialized)
{
// Dispose Thing
}
base.Dispose(disposing);
}
}
Although, if this pattern occurs in your code more than once, then i would definitely extend AsyncLazy

Configuring Ninject in App_start folder specifically ninjectwebcommon.cs file

I have a simple query, i am following the tutorial on this link:
http://www.prideparrot.com/blog/archive/2012/12/how_to_create_a_simple_blog_part1#book-unique-identifier
My problem is the author on this tutorial configure ninject in the global.asax file and deleted the ninjectwebcommon.cs file. i am trying to integrate the justblog into my existing asp.netMVC5 application that is using the ninjectwebcommon.cs file.
Any help would be much appreciated.
Did you use Nuget to add Ninject? You'll need a reference to WebActivatorEx for the bootstrapper to work (obviously along with the other required Ninject references). Add a NinjectWebCommon.cs class in your App_Start folder in your project, looking like this:
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(YourMvcApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(YourMvcApp.App_Start.NinjectWebCommon), "Stop")]
namespace YourMvcApp.App_Start
{
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(); // you'll add modules to the parameter list here
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)
//{
//}
}
}

i can't create a static method in Nop.Services.Customers.CustomerService

I try to create a static function in Nop.Services.Customers.CustomerService for get
customer list in the nop database. I want to call this function in an external Console
Application. But CustomerService class not contains the default constructor.
Please see the constructor code.
#region Ctor
/// <summary>
/// Ctor
/// </summary>
/// <param name="cacheManager">Cache manager</param>
/// <param name="customerRepository">Customer repository</param>
/// <param name="customerRoleRepository">Customer role repository</param>
/// <param name="customerAttributeRepository">Customer attribute repository</param>
/// <param name="encryptionService">Encryption service</param>
/// <param name="newsLetterSubscriptionService">Newsletter subscription service</param>
/// <param name="rewardPointsSettings">Reward points settings</param>
/// <param name="customerSettings">Customer settings</param>
/// <param name="eventPublisher"></param>
public CustomerService(ICacheManager cacheManager,
IRepository<Customer> customerRepository,
IRepository<CustomerRole> customerRoleRepository,
IRepository<CustomerAttribute> customerAttributeRepository,
IEncryptionService encryptionService, INewsLetterSubscriptionService newsLetterSubscriptionService,
RewardPointsSettings rewardPointsSettings, CustomerSettings customerSettings,
IEventPublisher eventPublisher)
{
_cacheManager = cacheManager;
_customerRepository = customerRepository;
_customerRoleRepository = customerRoleRepository;
_customerAttributeRepository = customerAttributeRepository;
_encryptionService = encryptionService;
_newsLetterSubscriptionService = newsLetterSubscriptionService;
_rewardPointsSettings = rewardPointsSettings;
_customerSettings = customerSettings;
_eventPublisher = eventPublisher;
}
#endregion
And Fileds is shows the error when try to call in the static function.
Please see the fields
#region Fields
private readonly IRepository<Customer> _customerRepository;
private readonly IRepository<CustomerRole> _customerRoleRepository;
private readonly IRepository<CustomerAttribute> _customerAttributeRepository;
private readonly IRepository<FileUpload> _fileuploadRepository;
private readonly IEncryptionService _encryptionService;
private readonly ICacheManager _cacheManager;
private readonly INewsLetterSubscriptionService _newsLetterSubscriptionService;
private readonly RewardPointsSettings _rewardPointsSettings;
private readonly CustomerSettings _customerSettings;
private readonly IEventPublisher _eventPublisher;
#endregion
I create a default in CustomerService class.
public CustomerService()
{
}
and create new function in CustomerService
public virtual List<Customer> GetClients()
{
var _cust = _customerRepository.Table;
return _cust.ToList();
}
and call this function in an external console application
private static CustomerService _customerService = new CustomerService();
static void Main(string[] args)
{
List<Customer> cust = _customerService.GetClients();
ThreadStart start = new ThreadStart(ProcessMails);
thread = new Thread(start);
ProcessStatus = 1;
thread.Start();
}
But when i call this function it's shows the null error.
It's not possible to create a function in Nop.Core and call in an external application?
Please help.
From class definition, it is not possible. Static methods are for the type, not for the instance, so the member variable can be used in a static method should be static too.

How to ensure that my class Initialize method is called only once, what would be the best approach?

I'm currently using Unity IoC Container and here is my AppConfig class. As you can see the Initialize method should be called only once and I have used double lock checking to ensure that.
What would be the best way to implement achieve this if my approach is not the best way?
public interface IAppConfig
{
/// <summary>
/// Gets the admin username.
/// </summary>
/// <value>The admin username.</value>
string AdminUsername { get; }
/// <summary>
/// Gets the admin password.
/// </summary>
/// <value>The admin password.</value>
string AdminPassword { get; }
/// <summary>
/// Initializes this instance.
/// </summary>
void Initialize();
}
/// <summary>
/// A singleton App config which helps reading from web.config
/// its lifetime is controlled by Unity.
/// </summary>
public class AppConfig : IAppConfig
{
#region Fields
/// <summary>
/// the injectable config manager
/// </summary>
private readonly IConfigManager _configManager;
private readonly ILogger _logger;
private static readonly object LockObject = new object();
private static bool _initialized = false;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AppConfig"/> class.
/// </summary>
public AppConfig(IConfigManager configManager, ILogger logger)
{
this._configManager = configManager;
this._logger = logger;
}
#endregion
#region Properties
/// <summary>
/// Gets the admin username.
/// </summary>
/// <value>The admin username.</value>
public string AdminUsername { get; private set; }
/// <summary>
/// Gets the admin password.
/// </summary>
/// <value>The admin password.</value>
public string AdminPassword { get; private set; }
#endregion
#region Methods
public void Initialize()
{
if (_initialized)
{
throw new ApplicationException("Initialize method should be called only once");
}
lock(LockObject)
{
if (_initialized) return;
var adminUserNameSetting = _configManager.AppSettings[ConfigKeys.AdminUsername];
if (adminUserNameSetting == null)
{
throw new ApplicationException("AdminUsername key not found");
}
this.AdminUsername = adminUserNameSetting.Value;
if (String.IsNullOrWhiteSpace(this.AdminUsername))
{
_logger.LogError("AdminUsername not found");
}
// log
var adminPasswordSetting = _configManager.AppSettings[ConfigKeys.AdminPassword];
if (adminPasswordSetting == null)
{
throw new ApplicationException("AdminPassword key not found");
}
this.AdminPassword = adminPasswordSetting.Value;
if (String.IsNullOrWhiteSpace(this.AdminPassword))
{
_logger.LogError("AdminPassword not found");
}
_initialized = true;
}
}
#endregion
}
In the Unity, I'm using the below code:
// IAppConfig
container.RegisterType<IAppConfig, AppConfig>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(configManager,
logger));
var appConfig = container.Resolve<IAppConfig>();
appConfig.Initialize();
I think an Initalize() method tastes more like an implementation issue. And that means that maybe it shouldn't be in the interface at all.
Initializing an instance is best left to the constructor.
If you really need a delayed Initialize then you solution with a bool and a lock seems OK.
Judging by what you are doing in the Initialize method, I think what you need to look into is registering that class as a singleton and persisting the container. You can see an example of doing this here:
http://gunnarpeipman.com/2008/04/unity-and-singletons/
Okay so you're relying on Unity to ensure that you class is a singleton. Although the code pattern for C# is quite easy. See here. Then call initialisation code in the constructor.
In any case I would declare your initialization flag volatile as the code stands atmo.
I prefer to have a static class instance variable that checks to see if it has been initialized in the get accessor. Access the class through the instance property and you will control how many times the class is initialized. This is pretty much the default C# singleton pattern:
public static class MySingleton
{
private static Mutex instanceLock = new Mutex();
private static MySingleton instance;
public static MySingleton Instance
{
get
{
instanceLock.WaitOne();
if(instance == null)
{
instance = new MySingleton();
}
instanceLock.ReleaseMutex();
return instance;
}
}
private MySingleton()
{
Initialize();
}
private void Initialize()
{
// Initialize
}
}
public class MyOtherClass
{
private MySingleton singleton = MySingleton.Instance;
}

Categories