Autofac RegisterAssemblyTypes for classes without default constructor - autofac

I am using Autofac 2.4.5.724 under vb.net 2010. I have several classes without default constructors that I want autofac to resolve, and I want to register them using RegisterAssemblyTypes (not registering the classes one by one). Is it possible?
My interface is like this:
Namespace Repo
Public Interface IPeople
Function All() As IList(Of RCO.People)
End Interface
End Namespace
The implementation is like this:
Namespace Repo
Public Class People
Inherits Base
Implements IPeople
Public Sub New(ByVal cs As String)
MyBase.New(cs)
End Sub
Public Function All() As IList(Of RCO.People) Implements IPeople.All
...
End Function
End Class
End Namespace
I can register the classes one by one like this:
Dim builder = New ContainerBuilder
builder.Register(
Function(x) New MyLib.Repo.People("Data Source=localhost...")
).As(Of MyLib.Repo.IPeople)()
Dim container = builder.Build
Dim peep = container.Resolve(Of MyLib.Repo.IPeople)()
But I don't want to register the classes one by one, I want autofac to scan my assembly:
Dim builder = New ContainerBuilder
builder.RegisterAssemblyTypes(Reflection.Assembly.Load("MyLib")).Where(
Function(x) x.Namespace = "Repo").AsImplementedInterfaces() ...what else?...
Dim container = builder.Build
Dim peeprepo = container.Resolve(Of ReportCenterLib.Repo.IPeople)()
Alternatively, can I put constructor parameter during resolve?
Dim peeprepo = container.Resolve(Of ReportCenterLib.Repo.IPeople)(...here?...)

You can definitely specify the parameter when resolving. You just need to add one or more TypedParameters created using the actual parameters to the Resolve call; you can't pass them directly:
Dim peeprepo = container.Resolve(Of ReportCenterLib.Repo.IPeople)(TypedParameter.From("Data Source=localhost..."))
Now, when Autofac sees a constructor for the registered type that accepts a string, it will substitute the given parameter. Understand that Autofac will get confused if you have a constructor that takes multiple strings; in that case, you'll need to specify each string as a named parameter which Autofac will match to the constructor parameter names. This has its own complexities; see the SO question here: Autofac parameter passing

In your particular example, where you're talking about a db connection, instead of accepting a String representing the connection string, you could accept a Func<SqlConnection> and then register SqlConnection separately. Then you could let Autofac auto-resolve the Func<SqlConnection>. This would avoid the need to specify the parameter explicity during registration.

Related

Flutter Classes Objects are accessing private fields without getters

Hi, I am quite a bit confused, why main method can access private fields.
void main() {
A obj = A();
obj._b = 'a';
print(obj._b);
}
class A {
String _b;
}
output:- a
please see the screenshot that theres no error.
Unlike Java, Dart doesn’t have the keywords public, protected, and private.
There's no keyword or annotation so you can declare a field/function as private on class level, but you can declare a field/function as private member on lib scope.Read
So lets come to your question, your main method is able to access a field started with '_' because there are in the same package. Create a new file and move your class to that file, and you will not be able to access the private member.
So,
identifiers that start with an underscore (_) are visible only inside the library.
In dart _ (underscore) sign is encapsulating fields on namespace level, not class level. For class level encapsulation ( still not private but protected ) consider using #protected annotation for the fields or move your class to a separate file.
I think this is the answer of you question right #umar_baloch.

HTL Access Property Without Getter

I'm writing an AEM component and I have an object being returned that is a type from an SDK. This type has public properties and no getters. For simplicity, it might be defined like this:
class MyItem {
public String prop1;
public String prop2;
}
Now normally, I would need a getter, like so:
class MyItem {
public String prop1;
public String prop2;
public String getProp1() {
return prop1;
}
}
But I do not have this luxury. Right now, I've got a Java implementation that uses another type to resolve this, but I think it's sort of crazy that HTL doesn't allow me to just access prop1 directly (it calls the getter). I've reviewed the documentation and can't see any indication of how this could be done. I'd like to be able to write:
${item.prop1}
And have it access the public property instead of calling getProp1().
Is this possible?
You don't need getters for public fields if those fields were declared by your Java Use-class. There's actually a test in Apache Sling that covers this scenario:
https://github.com/apache/sling/blob/trunk/bundles/scripting/sightly/testing-content/src/main/resources/SLING-INF/apps/sightly/scripts/use/repopojo.html
This also applies to Use-classes exported from bundles.
For Sling Models using the adapter pattern [0] I've created https://issues.apache.org/jira/browse/SLING-7075.
[0] - https://sling.apache.org/documentation/bundles/models.html#specifying-an-alternate-adapter-class-since-110
From the official documentation
Once the use-class has initialized, the HTL file is run. During this stage HTL will typically pull in the state of various member variables of the use-class and render them for presentation.
To provide access to these values from within the HTL file you must define custom getter methods in the use-class according to the following naming convention:
A method of the form getXyz will expose within the HTL file an object property called xyz.
For example, in the following example, the methods getTitle and getDescription result in the object properties title and description becoming accessible within the context of the HTL file:
The HTL parser does enumerate all the public properties just like any java enumeration of public fuields which include getters and public memebers.
Although it is questionable on whether you should have public variable but thats not part of this discussion. In essence ot should work as pointed by others.

Unity Registration: Hooking up an interface to a pre-registered concrete class

I already have a concrete class registered in my unity container and I want to, later on, register an interface that hooks up to that class but uses the existing registration.
I can do this using the following code but it causes a resolve at registration time...
container.RegisterInstance<IMyClass>(container.Resolve<MyClass>());
Is it possible to hook the code up with all resolution done at the point the interface is resolved?
The trick is to use an InjectionFactory:
container.Register<IMyClass>(
new InjectionFactory(c => c.Resolve<MyClass>()));
It sounds like you want to create a factory type. Here, a Func delegate type is used to avoid the creation of a new custom factory type:
container.RegisterInstance<Func<IMyClass>>(() => container.Resolve<MyClass>());
Your other types can then take a dependency on this factory:
private IMyClass myClass;
public MyOtherType(Func<IMyClass> myClassFactory)
{
this.myClass = myClassFactory();
}
IUnityContainer container = new UnityContainer();
var onlyInstance = new MyClass();
container.RegisterInstance<IMyClass>(onlyInstance);
IMyClass resolved = container.Resolve<IMyClass>();
if (object.ReferenceEquals(onlyInstance, resolved))
{
Console.WriteLine("Equal");
}
This prints "Equal". This is the way I would register the instance in the first place.
In a comment above, you imply that you do not control the initial registration. That's the real issue. I would recommend going down one of the following paths (in order of preference, highest to lowest):
Create your own UnityContainer independent of the pre-registered one
Create a child container with CreateChildContainer
Use named (non-default) mappings

XML generation in ASP.NET 2.0 web services?

I'm building a web service (.asmx) with ASP 2.0, and a lot of my methods return custom objects. It's always converted my objects into XML for me using the properties of the objects, but I've run into a situation where it doesn't.
I need to return a bunch of objects of different classes at once, and the classes are unfortunately not related through inheritance, so I'm returning an array of objects from my web method. The output looks like this:
<ArrayOfAnyType>
<anyType xsi:type="Type1"/>
<anyType xsi:type="Type2"/>
</ArrayOfAnyType>
The Type1 and Type2 classes have properties defined, but they're not auto-implemented, and they're read only. All properties I've seen auto-converted into XML so far have been fully auto-implemented. Is this why it doesn't convert properly? Am I going to have to redesign my classes to get this to work, or is there an attribute I can add somewhere, or an interface I can implement, or something like that?
My class declarations look like this:
Public Class Type1
Dim _var1 As Decimal
Public Sub New()
Dim conn As New SqlConnection(ConfigurationManager.AppSettings("myString"))
conn.Open()
Dim command As New SqlCommand("SELECT * FROM table1", conn)
Dim reader As SqlDataReader = command.ExecuteReader()
reader.Read()
_var1 = reader("Var1")
reader.Close()
conn.Close()
End Sub
Public ReadOnly Property Var1() As Decimal
Get
Return _var1
End Get
End Property
End Class
EDIT: clarifying my question: why is the XML serialization process ignoring my properties in this class? Because they're not auto-implemented? Or because they're read only? Or something else?
XML Serialization only works with public, read/write properties. Sorry, but your read-only properties will never be serialized.
ASP.NET 2.0 web services run off the XML Serializer in System.Xml.Serialization (if memory serves) and the related attributes there such as XmlIgnore().
Unfortunately, getting that to work with a polymorphic collection can be a bit of a trick. If it is a limited number of classes, the easiest way out would be to do something like:
public class Shelf
{
public Bottle[] Bottles {get; set;}
public Box[] Boxes {get; set;}
}
It might be worth looking at WCF here, it has much better options.

Class design: file conversion logic and class design

This is pretty basic, but sort of a generic issue so I want to hear what people's thoughts are. I have a situation where I need to take an existing MSI file and update it with a few standard modifications and spit out a new MSI file (duplication of old file with changes).
I started writing this with a few public methods and a basic input path for the original MSI. The thing is, for this to work properly, a strict path of calls has to be followed from the caller:
var custom = CustomPackage(sourcemsipath);
custom.Duplicate(targetmsipath);
custom.Upgrade();
custom.Save();
custom.WriteSmsXmlFile(targetxmlpath);
Would it be better to put all the conversion logic as part of the constructor instead of making them available as public methods? (in order to avoid having the caller have to know what the "proper order" is):
var custom = CustomPackage(sourcemsipath, targetmsipath); // saves converted msi
custom.WriteSmsXmlFile(targetxmlpath); // saves optional xml for sms
The constructor would then directly duplicate the MSI file, upgrade it and save it to the target location. The "WriteSmsXmlFile is still a public method since it is not always required.
Personally I don't like to have the constructor actually "do stuff" - I prefer to be able to call public methods, but it seems wrong to assume that the caller should know the proper order of calls?
An alternative would be to duplicate the file first, and then pass the duplicated file to the constructor - but it seems better to have the class do this on its own.
Maybe I got it all backwards and need two classes instead: SourcePackage, TargetPackage and pass the SourcePackage into the constructor of the TargetPackage?
I'd go with your first thought: put all of the conversion logic into one place. No reason to expose that sequence to users.
Incidentally, I agree with you about not putting actions into a constructor. I'd probably not do this in the constructor, and instead do it in a separate converter method, but that's personal taste.
It may be just me, but the thought of a constructor doing all these things makes me shiver. But why not provide a static method, which does all this:
public class CustomPackage
{
private CustomPackage(String sourcePath)
{
...
}
public static CustomPackage Create(String sourcePath, String targetPath)
{
var custom = CustomPackage(sourcePath);
custom.Duplicate(targetPath);
custom.Upgrade();
custom.Save();
return custom;
}
}
The actual advantage of this method is, that you won't have to give out an instance of CustomPackage unless the conversion process actually succeeded (safe of the optional parts).
Edit In C#, this factory method can even be used (by using delegates) as a "true" factory according to the Factory Pattern:
public interface ICustomizedPackage
{
...
}
public class CustomPackage: ICustomizedPackage
{
...
}
public class Consumer
{
public delegate ICustomizedPackage Factory(String,String);
private Factory factory;
public Consumer(Factory factory)
{
this.factory = factory;
}
private ICustomizedPackage CreatePackage()
{
return factory.Invoke(..., ...);
}
...
}
and later:
new Consumer(CustomPackage.Create);
You're right to think that the constructor shouldn't do any more work than to simply initialize the object.
Sounds to me like what you need is a Convert(targetmsipath) function that wraps the calls to Duplicate, Upgrade and Save, thereby removing the need for the caller to know the correct order of operations, while at the same time keeping the logic out of the constructor.
You can also overload it to include a targetxmlpath parameter that, when supplied, also calls the WriteSmsXmlFile function. That way all the related operations are called from the same function on the caller's side and the order of operations is always correct.
In such situations I typicaly use the following design:
var task = new Task(src, dst); // required params goes to constructor
task.Progress = ProgressHandler; // optional params setup
task.Run();
I think there are service-oriented ways and object-oritented ways.
The service-oriented way would be to create series of filters that passes along an immutable data transfer object (entity).
var service1 = new Msi1Service();
var msi1 = service1.ReadFromFile(sourceMsiPath);
var service2 = new MsiCustomService();
var msi2 = service2.Convert(msi1);
service2.WriteToFile(msi2, targetMsiPath);
service2.WriteSmsXmlFile(msi2, targetXmlPath);
The object-oriented ways can use decorator pattern.
var decoratedMsi = new CustomMsiDecorator(new MsiFile(sourceMsiPath));
decoratedMsi.WriteToFile(targetMsiPath);
decoratedMsi.WriteSmsXmlFile(targetXmlPath);