Let's say you have an interface of IModel that takes a pair of generics ...
public interface IModel<TOne, TTwo>
{
TOne ConvertToOne(TTwo two);
TTwo ConvertToTwo(TOne one);
}
and a class that implements this
public class OneTwo : IModel<SomethingOne, SomethingTwo>
{
SomethingOne ConvertToOne(SomethingTwo two)
{ //zomg! nothing exciting!
}
...
}
Nothing overly fancy. In my mapping configs, I have a list that looks kind of like this ...
For<IModel<SomethingOne, SomethingTwo>>().Use<OneTwo>();
For<IModel<SomeOne, SomeTwo>>().Use<AnotherClass>();
and so on. Based on DRY, I feel like this is the hard way to do this (there's 7 of them now, soon to be 20 or so). Anyway to do this "more better"?
You could try this... it might work.
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.AssemblyContainingType<Something>();
scan.ConnectImplementationsToTypesClosing(typeof(IModel<,>));
}
}
Related
I am busy developing my first non-example Orchard module. It is a handful of controllers and views, with custom (EF) data access, and is largely independent of Orchard content types and parts. Normally I set up mappings in an Application_Start handler, but as the actions in this MVC module will be invoked in the context of the Orchard application, I no longer have that point of entry. My most obvious and immediate solution is to move mapping initialization into static constructors for mapped view models, e.g.
public class ApplicantPersonalDetailsModel : MappedViewModel<Applicant>
{
static ApplicantPersonalDetailsModel()
{
Mapper.CreateMap<Applicant, ApplicantPersonalDetailsModel>().Bidirectional();
}
....
}
How else can I do this? is there a better way to do this in MVC3/4 in general, or preferably, an event or hook I can grab in the Orchard application to also achieve this on applicaion startup?
The way I have done it is by implementing IOrchardShellEvents
public class MenuOrchardShellEvents : IOrchardShellEvents
{
public void Activated()
{
Mapper.CreateMap<YSRB.Menu.Models.Records.Customer, YSRB.Menu.Models.ViewModels.CustomerViewModel>()
.ForMember(c => c.CustomerType,
m => m.MapFrom(
x => (CustomerTypes)x.CustomerType
)
);
Mapper.CreateMap<YSRB.Menu.Models.ViewModels.CustomerViewModel, YSRB.Menu.Models.Records.Customer>()
.ForMember(c => c.CustomerType,
m => m.MapFrom(
x => (int)x.CustomerType
)
);
}
public void Terminating()
{
//Do nothing
}
}
Hope this helps.
The Handler is the best place for initializing your variables, even if you haven't defined any part inside your module you can define one without a driver but with handler.
public class InitPartHandler : ContentHandler
{
public InitPartHandler(IRepository<InitPartRecord> repository)
{
OnInitializing<InitPart>((context, part) =>
// do your initialization here
);
}
}
EDIT
InitPart and InitPartRecord would be
public class InitPart : ContentPart<InitPartRecord>
{
}
public class InitPartRecord : ContentPartRecord
{
}
I have Razor function which outputs some data and as result does not return anything (that's a long story why it is done this way):
#functions
{
public static void SampleHelperMethod()
{
//...
}
}
How can I call it in view now? I tried #MyFunctions.SampleHelperMethod() but it doesn't work for void functions.
Declaration
#functions
{
public static void TestFunction()
{
}
}
Use in View
#{ TestFunction(); }
Because this is a function that does not return anything, you need to wrap it in the braces like you would and if/for statement. However, like Erik said, it is really unclear why this logic would be declared in the view...you may consider creating a helpers class that your views can include. This will allow for reuse and better separations of concerns.
I'm using Ninject 2.0 to handle DI in one of my apps and I've come across something that's confusing me. Having zero documentation doesn't help too much either to be honest.
Say I have a constructor with the signature -
ctor(IServiceFactory factory1, IServiceFactory factory2)
{
this.factory1 = factory1;
this.factory2 = factory2;
}
Although these two services implement the same interface, they are quite different implementations and are used at different times so I don't want to inject an IEnumerable<IServiceFactory>.
My question is, when I'm binding the instances, how do I tell Ninject what to inject for each?
Thanks in advance.
Update
For the sake of anyone wanting to see the code would end up after reading Remo's links,...Here it is in brief. (I never realised C# had parameter attributes!)
//abstract factory
public interface IServiceFactory
{
Service Create();
}
//concrete factories
public class Service1Factory : IServiceFactory
{
public IService Create()
{
return new Service1();
}
}
public class Service2Factory : IServiceFactory
{
public IService Create()
{
return new Service2();
}
}
//Binding Module (in composition root)
public class ServiceFactoryModule : NinjectModule
{
public override void Load()
{
Bind<IServiceFactory>()
.To<Service1Factory>()
.Named("Service1");
Bind<IServiceFactory>()
.To<Service2Factory>()
.Named("Service2");
}
}
//consumer of bindings
public class Consumer(
[Named("Service1")] service1Factory,
[Named("Service2")] service2Factory)
{
}
First of all you have to ask yourself if using the same interface is correct if the implementations need to do a completely different thing. Normally, the interface is the contract between the consumer and the implementation. So if the consumer expects different things then you might consider to define different interfaces.
If you decide to stay with the same interface than you have to use conditional bindings. See the documentation about how this is done:
https://github.com/ninject/ninject/wiki/Contextual-Binding
https://github.com/ninject/ninject/wiki/Conventions-Based-Binding
I using StructureMap to create instances of ModuleData
I have many classes that inherit from ModuleData(class A,B,C...) and each of them get Config1 or Config2 in coustructor
In Registry(located in file1.cs) I scan all types of ModuleData.
In Get(lacated in file2.cs) I get the instance.
I want that when ObjectFactory creates Config1/Config2 while creating instance of ModuleData it will pass "param" to Config1/Config2 constructors.
How I can configure structuremap to do this?
P.S. Registry & Get methods are located in different files!!!
Thank you
public class Config1
{
Config1(string param)
{
}
}
public class Config2
{
Config2(string param)
{
}
}
//.....//
public class A : ModuleData
{
A(Config1 c)
{
}
}
public class B : ModuleData
{
A(Config2 c)
{
}
}
//....//
//located in file1.cs
public Registry()
{
Scan(x =>
{
x.TheCallingAssembly();
x.AddAllTypesOf<ModuleData>();
});
ObjectFactory.Initialize(x =>
{
x.For<Config1>().Use<Config1>();
x.For<Config2>().Use<Config2>();
});
}
//....//
//located in file2.cs
public ModuleData Get(object o)
{
var module = o as PageModule;
var t = Type.GetType(string.Format("{0}.{1},{2}", Settings.Namespace, module.Name, Settings.Assembly));
return ObjectFactory.With("param").EqualTo(module.Parameters).GetInstance(t) as ModuleData;
}
I can't think of a good way to do what you want, I think its a bit of a design problem... I think you would have to explain a bit more about why you need to do this for me to help you.
What is a page module? Why is your config objects dependent on it?
Based on your comment, I think what you need is a factory object that creates ModuleData objects for you. Since they are objects it does not make much sense to get them from the container. Think about using a data access technology like Entity Framework, it would not make sense to get those objects from the container. From what I can tell, this is a similar case.
Dependency injection seems to be a good thing. In general, should dependencies be injected at the methods that require them, or should they be injected in the contructor of the class?
See the samples below to demonstrate the two ways to inject the same dependency.
//Inject the dependency into the methods that require ImportantClass
Class Something {
public Something()
{
//empty
}
public void A()
{
//do something without x
}
public void B(ImportantClass x)
{
//do something with x
}
public void C(ImportantClass x)
{
//do something with x
}
}
//Inject the dependency into the constructor once
Class Something {
private ImportantClass _x
public Something(ImportantClass x)
{
this._x = x;
}
public void A()
{
//do something without x
}
public void B()
{
//do something with this._x
}
public void C()
{
//do something with this._x
}
}
The major benefit of constructor injection is that it allows your fields to be marked final. For example:
class Foo {
private final Bar _bar;
Foo(Bar bar) {
_bar=bar;
}
}
The following page has a great list of the pro's and con's: Guice Best Practices:
Method injection
+ Isn't field injection
+ Only thing that works for some strange edge cases
Constructor injection
+ Fields can be final!
+ Injection cannot possibly have been skipped
+ Easy to see dependencies at a glance
+ It's what the idea of construction is all about
- No optional injections
- Useless when DI library can't do instantiation itself
- Subclasses need to "know about" the injections needed by their superclasses
- Less convenient for tests that only "care about" one of the parameters
If you inject during the methods than you are not differentiating the behavioral abstraction from the concrete dependencies. This is a big no no :). You want to depend on abstractions so you are not coupled with the dependencies of your classes dependencies . . .
Since your constructor would not be there in any interface that your concrete class supports than you are not coupling to that dependency. But the method calls would have that issue.
Here is a good article on this tiopic:
http://chrisdonnan.com/blog/2007/05/20/conquest-through-extreme-composition-glue-part-2/
By not injecting the dependency at each method you then force each caller to know or retrieve the dependency.
Also from a tooling standpoint there are many frameworks available (at least in .NET) that enable or make constructor injection much easier to do. This should not sway the decision but makes it much more attractive.
Good luck.
Another method is to user a setter for the dependency. Sometimes this is combined with constructor injection. This can be useful if you want to change which implementation you are using later without having to recreate the instance.
public interface IFoo
{
void Do();
}
public class DefaultFoo : IFoo
{
public void Do()
{
}
}
public class UsesFoo
{
private IFoo foo;
public IFoo Foo
{
set { this.foo = value; }
}
public UsesFoo()
{
this.Foo = new DefaultFoo();
}
public UsesFoo( IFoo foo )
{
this.Foo = foo;
}
public void DoFoo()
{
this.Foo.Do();
}
}
Crazy Bob Lee says use constructor injection whenever possible. Only use method injection when you don't have control over instantiation (like in a servlet).