I was trying to write a method that returns a list of classes that implements an Interface, but could not do it.
Some method like
public List<Class> GetImplementedClasses(Interface Interface1)
{
. . .
}
I tried to use interface1.AllChildren and many other tries. Non of them gave any results.
Is it possible to write such a method using DXCore APIs?
EXAMPLE:
If I pass Interface1, I should get Class1 and Class2 from the method GetImplementedClasses.
Thanks in Advance.
There's a "GetDescendants" method in the Intrerface class that might be useful for your task. The code will look similar to this:
public List<Class> GetImplementedClasses(Interface Interface1)
{
List<Class> result = new List<Class>();
if (Interface1 != null)
{
ITypeElement[] descendants = Interface1.GetDescendants();
foreach (ITypeElement descendant in descendants)
{
if (!descendant.InReferencedAssembly)
{
Class classDescendant = descendant.ToLanguageElement() as Class;
if (classDescendant != null)
result.Add(classDescendant);
}
}
}
return result;
}
I'm not sure about dxcore, but in regular C# I've written an extension method which gets all the Types available in a deployment; you could use it like this:
Assembly.GetExecutingAssembly().GetAvailableTypes(
typeFilter: t =>
(t != typeof(interfaceType))
&&
typeof(interfaceType).IsAssignableFrom(t));
Related
I need to find a way to get an instance of DataProcessingEngine without calling it's constractor.
I am trying to find a way to do so using the registered DataProcessingEngine in composition object (please see the following code). But I could not find a way to do so.
Anyone have a suggestion? Thanks in advance.
public class Composer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IDataProcessingEngine, DataProcessingEngine>(Lifetime.Singleton);
//DataProcessingEngine dataProcessing = compostion.Resolve<IDataProcessingEngine>()??//no resolve function exists in Umbraco.Core.Composing
SaveImagesThread(dataProcessingEngine);
}
public Task SaveImagesThread(IDataProcessingEngine dataProcessingEngine)//TODO - decide async
{
string dataTimerTime = WebConfig.SaveProductsDataTimer;
double time = GetTimeForTimer(dataTimerTime);
if (time > 0)
{
var aTimer = new System.Timers.Timer(time);
aTimer.Elapsed += new ElapsedEventHandler(dataProcessingEngine.SaveImages);
aTimer.Start();
}
return default;
}
}
For all of you who are looking for a way to call a function (that's defined in another class in your code, an Engine or ...) from the composer(where the app starts) and want to avoid calling this function's class' constractor. I've found another way to do so:
public class QueuePollingHandler
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToQueuePollingHandlerComponentComposer :
ComponentComposer<SubscribeToQueuePollingHandler>
{ }
public class SubscribeToQueuePollingHandler : IComponent
{
private readonly IDataProcessingEngine _dataProcessingEngine;
public SubscribeToQueuePollingHandler(IDataProcessingEngine
dataProcessingEngine)
{
_dataProcessingEngine = dataProcessingEngine;
SaveImagesThread(_dataProcessingEngine);
}
public void SaveImagesThread(IDataProcessingEngine
dataProcessingEngine)
{
....
}
}
And the logic explenation: You create a class (SubscribeToQueuePollingHandlerComponentComposer from the example) and define its base class to be ComponentComposer<Class_that_inherits_IComponent>.
And when you start the application you could see that it gets to the registered class' constractor (SubscribeToQueuePollingHandler constructor).
That's the way that I found to be able to call a function right when the application starts without needing to call its class constractor and actualy use dependency injection.
Hi I am just been looking at AutoFac and following their getting-started tutorial
http://autofac.readthedocs.org/en/latest/getting-started/index.html
having followed it and understanding how their services work I wanted to try to create a new implementation on the same interface type
builder.RegisterType<TodayWriter>().As<IDateWriter>();
builder.RegisterType<TomorrowWriter>().As<IDateWriter>();
Both implentations contain the same code
public class TomorrowWriter : IDateWriter
{
private IOutput _output;
public TomorrowWriter(IOutput output)
{
this._output = output;
}
public void WriteDate()
{
this._output.Write(DateTime.Today.AddDays(1).ToShortDateString());
}
}
So TodaysWriter is the same apart from the WriteDate method displaying
this._output.Write(DateTime.Today.ToShortDateString());
instead.
So now using the application, how do I determine what implementation to use as both methods are called WriteDate()
using(var scope = Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
// Is this using todaysWriter or TomorrowWriter?
writer.WriteDate();
}
Am I using this wrong?
Thanks
To differentiate between different implementations of the same interface look at named and keyed services in the docs.
Alternatively you can roll your own by registering a DateWriterFactory and having a method on that to get a specific IDateWriter implementation. something like:
public class DateWriterFactory
{
IDateWriter GetWriter(string writerName)
{
if (writername=="TodayWriter")
return new TodayWriter();
if (writername=="TomorrowWriter")
return new TomorrowWriter();
}
}
obviously the implementation of the factory could be as complex or as simple as you need. Or you could just have methods to get the fixed writers rather than pass in a string.
It appears the convention for converting objects in Groovy is to use the as operator and override asType(). For example:
class Id {
def value
#Override
public Object asType(Class type) {
if (type == FormattedId) {
return new FormattedId(value: value.toUpperCase())
}
}
}
def formattedId = new Id(value: "test") as FormattedId
However, Grails over-writes the implementation of asType() for all objects at runtime so that it can support idioms like render as JSON.
An alternative is to re-write the asType() in the Grails Bootstrap class as follows:
def init = { servletContext ->
Id.metaClass.asType = { Class type ->
if (type == FormattedId) {
return new FormattedId(value: value.toUpperCase())
}
}
}
However, this leads to code duplication (DRY) as you now need to repeat the above in both the Bootstrap and the Id class otherwise the as FormattedId will not work outside the Grails container.
What alternatives exist to writing conversion code in Groovy/Grails that do not break good code/OO design principals like the Single Responsibility Principal or DRY? Are Mixins are good use here?
You can use the Grails support for Codecs to automatically add encodeAs* functions to your Grails archetypes:
class FormattedIdCodec {
static encode = { target ->
new FormattedId((target as String).toUpperCase()
}
}
Then you can use the following in your code:
def formattedId = new Id(value: "test").encodeAsFormattedId
My un-elegant solution is to rename the original asType(), and make a new asType() that calls it, and to also make your BootStrap overwrite astType with a call to that method:
so, your class:
class Id {
def value
#Override
public Object asType(Class type) {
return oldAsType(type);
}
public Object oldAsType(Class type) {
if (type == FormattedId) {
return new FormattedId(value: value.toUpperCase())
}
}
}
In my app, I had asType defined in a number of classes, so I ended up using a common closure in BootStrap.groovy:
def useOldAsType = {Class clazz ->
delegate.oldAsType(clazz)
}
Id.metaClass.asType = useOldAsType;
Value.metaClass.asType = useOldAsType;
OtherClass.metaClass.asType = useOldAsType;
SubclassOfValue.metaClass.asType = useOldAsType;
Note that if you have a subclass that does not override asType, but you want it to use the superclass's, you must also set it in BootStrap.
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.
public class TheController : Controller
{
IThe the;
public TheController( IThe the)
{
//when User.IsInRole("r1") The1 should be injected else r2
this.the = the;
}
}
public class The1 : IThe{}
public class The2 : IThe{}
//anybody knows a good way of doing this ?
IHandlerSelector is the way to go. See this post for an example of usage.
Alternatively if you prefer AutoFac-like experience you can use factory for that:
container.Register(Component.For<IThe>().UsingFactoryMethod(
c => HttpContext.Current.User.IsInRole("r1") ?
c.Resolve<IThe>("r1") :
c.Resolve<IThe>("r2"));
Or if you want to use specific IThe just in one context, you can use DynamicParameters:
container.Register(Component.For<TheFactory>().Lifestyle.Transient.DynamicParameters(
(c, d) => HttpContext.Current.User.IsInRole("r1") ?
d["the"] = c.Resolve<IThe>("r1") :
c.Resolve<IThe>("r2"));
However the most correct way of doing this is IHandlerSelector
The container-agnostic approach obviously employs an Abstract Factory:
public interface ITheFactory
{
IThe Create(IPrincipal user);
}
You can take a dependency on ITheFactory instead of IThe:
public class TheController : Controller
{
private readonly IThe the;
public TheController(ITheFactory theFactory)
{
if (theFactory == null)
{
throw new ArgumentNullException("theFactory");
}
this.the = theFactory.Create(this.User);
}
}
I can't really remember if this.User is populated at this time, but if it isn't, you can just keep a reference to the factory and lazily resolve your dependency the first time it's requested.
However, Controller.User is a bit special because it ought to be available as Thread.CurrentPrincipal as well. This means that in this special case you don't actually have to introduce an Abstract Factory. Instead, you can write a Decorator that performs the selection every time it's used:
public class UserSelectingThe : IThe
{
private readonly IThe the1;
private readonly IThe the2;
public UserSelectingThe(IThe the1, IThe the2)
{
if (the1 == null)
{
throw new ArgumentNullException("the1");
}
if (the2 == null)
{
throw new ArgumentNullException("the2");
}
this.the1 = the1;
this.the2 = the2;
}
// Assuming IThe defines the Foo method:
public Baz Foo(string bar)
{
if (Thread.CurrentPrincipal.IsInRole("r1"))
{
return this.the1.Foo(bar);
}
return this.the2.Foo(bar);
}
}
In this case, you would be able to use your original TheController class unchanged.
In Autofac:
var builder = new ContainerBuilder();
// Give the different implementations names
builder.RegisterType<The1>.Named<IThe>("r1");
builder.RegisterType<The2>.Named<IThe>("r2");
// Use a function for the default IThe
builder.Register(
c => HttpContext.Current.User.IsInRole("r1") ?
c.Resolve<IThe>("r1") :
c.Resolve<IThe>("r2"))
.As<IThe>()
.ExternallyOwned();
If you have a lot of roles, you can use a method instead of the inline expression, e.g.:
builder.Register(c => ChooseTheImplementation(c))
(BTW, The "ExternallyOwned" modifier tells the container that the result of the function is disposed elsewhere, e.g. via the concrete components. You can usually leave it out but it makes good documentation :))