I have a httpHandler and using Unity 2 I would like to inject a dependency into my HttpHandler.
My code looks like:
public class MyHandler : BaseHandler
{
public MyHandler()
{
}
public IConfigurationManager Configuration
{
get;
set;
}
...
}
Using the web.config I would configure it like this (left out the rest of the config for simplicity) :
<type type="MyHandler">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
<property name="Configuration" propertyType="IConfigurationManager">
<dependency/>
</property>
</typeConfig>
</type>
How would I go about doing the same thing using fluent syntax? Everything I have tried so far leaves the property set to null when the handler fires.
Thanks
ConfigureInjectionFor has been obsolete since Unity 1.2 was released.
This should work:
container.RegisterType<MyHandler>(
new InjectionProperty("Configuration"));
You have to call the ConfigureInjectionFor method.
myContainer.Configure<InjectedMembers>()
.ConfigureInjectionFor<MyHandler>(
new InjectionProperty("Configuration",
new ResolvedParameter<IConfigurationManager>())
)
)
EDIT:
Here is an example of Handler factory. It allow you to create your handler
class HandlerFactory : IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext context, string requestType, String url, String pathTranslated)
{
return MyContainerProvider.Container.Resolve<MyHandler>();
}
public void ReleaseHandler(IHttpHandler handler)
{
}
public bool IsReusable
{
get { return false; }
}
}
Then, you have to register the factory in your web application (to allow IIS to find it). You can find more details here.
Related
i'm following Autofac guide to migrate to .net 3.1
According to their guide, I need to add (among other things) this function:
public void ConfigureContainer(ContainerBuilder builder)
And this will be called automatically
The problem is that the code inside it that is registering the services is conditional for our app so I need to pass a boolean to the function
for example:
public void ConfigureContainer(ContainerBuilder builder)
{
if (enableTokenAutoRefresh)
{
builder.RegisterType<AuthenticationWrapper>()
.As<IApiProxy>()
}
else
{
builder.RegisterType<ApiProxy>()
.As<IApiProxy>()
}
}
Can I just add a boolean to the ConfigureContainer method?
seems this will break the calling for it?
and if not - how to pass data to it ?
please help
ConfigureContainer, provided by the ASP.NET Core framework, only takes the container builder type of your DI framework (in this case, an Autofac ContainerBuilder). To get additional data in there, you'd need to set a variable on the Startup class somewhere earlier in the startup pipeline and use it.
// NOT a complete Startup, but gives you the idea.
public class Startup
{
public Startup(IConfiguration config)
{
// appSettings.json has the value you want
this.EnableTokenAutoRefresh = config.GetValue<bool>("path:to:key");
}
public bool EnableTokenAutoRefresh { get; set; }
public void ConfigureContainer(ContainerBuilder builder)
{
if(this.EnableTokenAutoRefresh)
{
// Do what you need to based on config
}
}
}
I have simple situation here. But NotifyPropertyChanged event is not raised even when I use viewmodel.Test = true. Is there some solution how to do that? Can I use some method to raise event manually? Somethin like OnPropertyChange(nameof(Test))? And is there some way how to track change in config too?
//From viewmodel with aspect NotifyPropertyChanged
private readonly IConfig config;
public bool Test
{
get { return config.Test; }
internal set
{
config.Test = value;
}
}
public class Config : IConfig
{
public bool Test { get; set; }
}
The Config class must have NotifyPropertyChanged aspect too.
http://support.sharpcrafters.com/discussions/problems/1862-notifypropertychanged-aspect-does-not-raise-events-for-proxied-objects-that-do-not-implement-inpc
I've got three projects:
UI
PluginManager
PluginOne
PluginTwo
Inside my Plugin Manager a create a simple plugin interface:
public interface IPlugin<T>
{
void sayMessage(T message);
T createMessage();
}
So, in my other projects I've two IPlugin implementation:
In porject PluginOneProject -->
-------------------------------
public class PluginOne : IPlugin<IntMessage>
{
public void sayMessage(IntMessage message)
{
System.Console.WriteLine(message.ToString());
}
}
where:
public class IntMessage
{
private int message;
public IntMessage(int message)
{
this.message = message;
}
public override string ToString()
{
return this.message.ToString();
}
}
In porject PluginTwoProject -->
-------------------------------
public class PluginTwo : IPlugin<StringMessage>
{
public void sayMessage(StringMessage message)
{
System.Console.WriteLine(message.ToString());
}
}
where:
public class StringMessage
{
private String message;
public StringMessage(String message)
{
this.message = message;
}
public override string ToString()
{
return this.message.ToString();
}
}
Obviously, I've added the corresponding project references.
So, in my UI porject I've NInject, and I perform this convention mapping:
kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(IPlugin<>))
.BindAllInterfaces()
);
The graph is built correctly.
So, I don't know how to get an instance of PluginOne, or PluginTwo from UI project.
I'm trying to use this code, however, I've a problem with generic interfaces...
foreach (IPlugin<?> plugin in kernel.GetAll(typeof(IPlugin<>)))
{
plugin.sayMessage(plugin.createMessage());
}
Unfortunately, you must request a specific interface from Ninject, so you must request either IPlugin<IntMessage> or IPlugin<StringMessage>.
I would suggest trying to refactor your app so that you can request a more generic interface, such as IPlugin, and/or create a message interface like IMessage that each message implements. It's not clear from your question what you're trying to accomplish.
When I implement the ICommand interface, the following methods are created
#region ICommand Members
public bool CanExecute(object parameter)
{
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
#endregion
The interesting part is
public void Execute(object parameter)
{
}
Simply because it indicates that it expects 1 parameter. What if I don't need to pass a parameter? In my ViewModel I have the following code
public class DownloadViewModel : BaseViewModel
{
public ICommand BrowseForFile { get; set; }
public string File { get; set; }
public DownloadViewModel()
{
BrowseForFile = new RelayCommand(new Action<object>(OpenDialog));
}
private void OpenDialog(object o)
{
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
File = dialog.SelectedPath;
}
}
The OpenDialog method does not require the parameter but it appears as if I have to just so I can satisfy the Interface.
Am I doing this right or have I missed the point?
Yes, ICommand always needs an object and RelayCommand too. If you don't need it, you pass null and don't use it in your method, which is ugly.
I would use Prism's DelegateCommand instead. This exists in a non-generic version, which doesn't take parameters:
Command = new DelegateCommand(DoSomething);
CommandWithParameter = new DelegateCommand<int>(DoSOmethingWithInt);
Its in the PRISM assembly, which you have to download and reference.
using Microsoft.Practices.Prism;
PRISM
Alternatively, use the MVVMLight toolkit, which provides a command class which does basically the same thing. There is no point in using MVVM without a MVVM framework anyway. I can recommend PRISM, also for it's basic stuff like the DelegateCommand or the EventAggregator.
The fact that Execute takes a parameter is irrelevant to the method from your ViewModel. The only thing that affects what parameters OpenDialog needs is your implementation of ICommand.
If your implementation is, for example:
public class MyRandomCommand : ICommand
{
private readonly Action _action;
public MyRandomCommand(Action action)
{
_action = action;
}
public void Execute(object parameter)
{
_action();
}
...
}
Then no parameters will be required for your OpenDialog method, as you can create a command as follows:
public ICommand Command { get { return new MyRandomCommand(OpenDialog); } }
You can, however, require any signature you like for the method you are passing to your command.
The most common, off-the-shelf implementations of RelayCommand can take methods with either 0 or 1 parameter and will be called from Execute appropriately.
I am trying to configure an application such that types from assemblyA can be used by my console to allow for logging in an AOP style. The JournalInterceptor will just write out method calls, input and maybe output arguments to a log file or datastore of some kind.
I can register one type at a time but I would like to register all types in one go. Once I get going I may add some filtering to the registered types but I am missing something.
I am trying to use Classes.FromAssemblyContaining but am not sure how to get at an IRegistration instance for the call to WindsorContainer::Register
Any clues?
// otherAssembly.cs
namespace assemblyA
{
public class Foo1 { public virtual void What(){} }
public class Foo2 { public virtual void Where(){} }
}
// program.cs
namespace console
{
using assemblyA;
public class JournalInterceptor : IInterceptor {}
public class Program
{
public static void Main()
{
var container = new Castle.Windsor.WindsorContainer()
.Register(
Component.For<JournalInterceptor>().LifeStyle.Transient,
// works but can't be the best way
Component.For<Foo1>().LifeStyle.Transient
.Interceptors<JournalInterceptor>(),
Component.For<Foo2>().LifeStyle.Transient,
.Interceptors<JournalInterceptor>(),
// how do I do it this way
Classes.FromAssemblyContaining<Foo1>()
.Pick()
.LifestyleTransient()
.Interceptors<JournalInterceptor>()
);
Foo1 foo = container.Resolve<Foo1>();
}
}
}
Implement a Pointcut. In Castle Windsor this is done by implementing the IModelInterceptorsSelector interface.
It would go something like this:
public class JournalPointcut : IModelInterceptorsSelector
{
public bool HasInterceptors(ComponentModel model)
{
return true; // intercept everything - probably not a good idea, though
}
public InterceptorReference[] SelectInterceptors(
ComponentModel model, InterceptorReference[] interceptors)
{
return new[]
{
InterceptorReference.ForType<JournalInterceptor>()
}.Concat(interceptors).ToArray();
}
}
Then register the Interceptor and the Pointcut with the container:
this.container.Register(Component.For<JounalInterceptor>());
this.container.Kernel.ProxyFactory.AddInterceptorSelector(new JournalPointcut());
For in-depth explanation, you may want to see this recording.