I want to reference owner class in its field. It is necessary to dispose these listeners or Dart GC can handle this case?
If owner object is not referenced outside anymore, GC can free up the whole object?
+1 case: 'FilterManager' have 3rd object (service) that still alive
class FilterManager {
SampleService service;
Val<String> search = ''.val;
FilterManager(this.service) {
search.addListener(onChange);
}
void onChange() {
service.filterChanged();
}
}
mixin ValChangeNotifier {
LinkedList<UpdateListenerEntry>? _listeners = LinkedList<UpdateListenerEntry>();
void addListener(UpdateVoidCallback listener) {
_listeners!.add(UpdateListenerEntry(listener));
}
...
}
Related
In my application I've noticed that if I mark a class in the SM registry as a Singleton type it gets disposed of, however if don't specify any Singleton it doesn't get disposed of.
What and why are the reasons for this?
public class IoC
{
public static IContainer Init()
{
var container = new Container(x =>
{
x.Scan(s => {
s.TheCallingAssembly();
s.AssembliesFromApplicationBaseDirectory();
s.WithDefaultConventions();
});
// disposed is called on this class but not if .Singleton() is removed
x.For<IMyService>().Singleton();
});
return container;
}
}
class Program
{
static void Main(string[] args)
{
using (var container = IoC.Init())
{
var theStory1 = container.GetInstance<MyService>();
theStory1.TheMethod();
}
}
}
Singleton lifecycle is bound to the container's scope thus when disposing the container it takes care to dispose all singletons implementing IDisposable. With transients and other lifecycles like HttpContextScoped it is up to developer to dispose them manually when no longer need them.
Transient disposables are tricky a little bit in terms of how it should be handled. Imagine case like this one below:
public class ClassWithDisposableTypeDependency
{
private readonly ISampleDisposable disposableType;
public ClassWithDisposableTypeDependency(ISampleDisposable disposableType)
{
this.disposableType = disposableType;
}
public void SomeAction()
{
using (this.disposableType)
{
this.disposableType.DoSomething();
}
}
}
What will happend when SomAction() won't be executed? Dispose won't be called on disposableType field. In fact in this case ClassWithDisposableTypeDependency should also implement IDisposable and dispose its disposable dependencies.
But there is a better way to handle such cases. In mentioned case the main issue is to defer creation of a dependency to a moment when we really need that objects. We can achieve that in many ways: func, lazy, factory, etc. Here is possible solution with usage of func.
public class ClassWithDisposableTypeFuncDependency
{
private readonly Func<ISampleDisposable> disposableTypeFactory;
public ClassWithDisposableTypeFuncDependency(Func<ISampleDisposable> disposableTypeFactory)
{
this.disposableTypeFactory = disposableTypeFactory;
}
public void SomeAction()
{
var disposable = this.disposableTypeFactory();
using (disposable)
{
disposable.DoSomething();
}
}
}
This is how we need to setup it in StructureMap:
var container = new Container(c => c.For<ISampleDisposable>().Use<SampleDisposable>());
var clazz = container.GetInstance<ClassWithDisposableTypeFuncDependency>();
clazz.SomeAction(); // dependency is created and disposed
Hope this helps!
I'm currently migrating away from Seam's #Factory annotation. Combined with #Observer, I could do this:
#Factory(value = "optionsList", scope = ScopeType.APPLICATION)
#Observer("entity.modified")
public List<MyBean> produceEntityOptions() {
List l = getEm().createQuery('select e from entity e').getResultList();
Contexts.getApplicationContext().set("optionsList", l);
return l;
}
Which would cache a list of possible options for use in e.g. <f:selectItems> (the actual computation can be more complicated).
I've translated this for use with CDI to
#Produces #Named("optionsList") #ApplicationScoped
public List<MyBean> produceEntityOptions() {
return getEm().createQuery('select e from entity e').getResultList();
}
but this loses the ability to recreate the cache (only) when an external event signals the cache has gone stale. How can I get that back?
Here's what you could do:
#ApplicationScoped
public class MyListProducer {
// the current list
private List<MyBean> listOfBeans;
// resets / reloads/ refreshes list
private void loadList() {
this.listOfBeans = getEm().createQuery('select e from entity e').getResultList();
}
// initialize the list
#PostConstruct
protected void postConstruct() {
loadList();
}
// listen for the stale event - you'll have to create a type (maybe even qualifiers) yourself
private void resetList(#Observes MyCustomListIsStaleEvent evt) {
loadList();
}
// the producer - to ensure that the producer is called after you refresh the list, make the list of scope #Dependent instead of #ApplicationScoped
#Produces #Named("optionsList")
protected List<MyBean> getList() {
return this.listOfBeans;
}
}
I think that in effect, this is what you want. But I don't exclude the possibility that there might be differences - don't know Seam very much.
Side note: You should think about synchronizing the observer and the producer methods, either with plain old synchronization or by making the above a stateful session bean and taking advantage of EJB synchronization mechanisms.
I'm working on an ASP.NET MVC project that support external plugins, now, I'm moving from Unity to Autofac and I need to wrap the lifetime objects of Autofac so the plugins won't have to reference it, in Unity I could do something this.
public sealed class UnityScopeFactory : IDependencyScopeFactory
{
private HttpRequestScope _httpRequest;
private SingletonScope _singleton;
private TransientScope _transient;
public IDependencyScope HttpRequest()
{
return _httpRequest ?? (_httpRequest = new HttpRequestScope());
}
public IDependencyScope Singleton()
{
return _singleton ?? (_singleton = new SingletonScope());
}
public IDependencyScope Transient()
{
return _transient ?? (_transient = new TransientScope());
}
private class HttpRequestScope : IDependencyScope
{
public object CreateScope()
{
return new HttpPerRequestLifetimeManager();
}
}
private class SingletonScope : IDependencyScope
{
public object CreateScope()
{
return new ContainerControlledLifetimeManager();
}
}
private class TransientScope : IDependencyScope
{
public object CreateScope()
{
return new TransientLifetimeManager();
}
}
}
I made similar thing in Autofac but I'm not sure whether it's the correct way to do that, I looked into the RegistrationBuilder of Autofac which is (unfortunately) internal and I came up with this.
public class AutofacScopeFactory : IDependencyScopeFactory
{
private HttpRequestScope _httpRequest;
private SingletonScope _singleton;
private TransientScope _transient;
public IDependencyScope HttpRequest()
{
return _httpRequest ?? (_httpRequest = new HttpRequestScope());
}
public IDependencyScope Singleton()
{
return _singleton ?? (_singleton = new SingletonScope());
}
public IDependencyScope Transient()
{
return _transient ?? (_transient = new TransientScope());
}
private class HttpRequestScope : IDependencyScope
{
public object CreateScope()
{
return new CurrentScopeLifetime();
}
}
private class SingletonScope : IDependencyScope
{
public object CreateScope()
{
return new RootScopeLifetime();
}
}
private class TransientScope : IDependencyScope
{
public object CreateScope()
{
return new CurrentScopeLifetime();
}
}
}
Also, after I got this to work, how can I use pass it to the ContainerBuilder?
In Unity I could do something like this.
public sealed class UnityDependencyContainer : IDependencyContainer
{
private readonly IUnityContainer _container;
public UnityDependencyContainer()
{
_container = new UnityContainer()
}
public void Register<TContract, TImplementation>(IDependencyScope scope) where TImplementation : TContract
{
LifetimeManager manager = scope.CreateScope() as LifetimeManager;
if (manager != null)
{
_container.RegisterType<TContract, TImplementation>(manager);
}
}
}
How do I pass an instance of IComponentLifetime to the method chain? is it a dead end?
public class AutofacContainer : IDependencyContainer
{
private static readonly ContainerBuilder Builder;
static AutofacContainer()
{
Builder = new ContainerBuilder();
}
public void RegisterType<TContract, TImplementation>(IDependencyScope scope) where TImplementation : TContract
{
IComponentLifetime manager = scope.CreateScope() as IComponentLifetime;
if (manager != null)
{
Builder.RegisterType<TImplementation>().As<TContract>();
}
}
}
Autofac doesn't separate scopes quite the way you have it outlined, so you might be trying to fit a square peg in a round hole.
Autofac scopes are more hierarchical. Any lifetime scope can spawn a child transient scope. For example, you might see...
Container/root lifetime
HttpRequest scope
Small task-specific transient scope
You can "tag" a scope and register components to a specific named/tagged scope - that's how the HttpRequest scope works. It gets "tagged" with a special identifier.
When you resolve objects is when it determines which lifetime scope owns it. Resolving happens from the most-nested scope. In the above hierarchy, you resolve items from the small task-specific transient scope whether they're singletons, request scoped, or whatever. When the singleton gets resolved, it will search up the lifetime scope stack and automatically assign "ownership" of the object to the root lifetime scope. When a per-request item gets resolved, it searches up the stack for the lifetime scope with the special "HTTP request" identifier and assigns ownership there. Factory-scoped items are resolved in the current lifetime scope.
Note: That discussion is a gross oversimplification of how it works. There is documentation explaining the lifetime scope mechanism on the Autofac site.
Point being, I see some things in the above design that don't really "jive" with the way Autofac does stuff.
The DependencyScopeFactory can't create its own transient or HttpRequest scopes. There are specific lifetime management components that start and end the HttpRequest scope, so you'd need to use those; there is no 'global' transient scope, so you can't really just create one.
HttpRequest scope, assuming you're using MVC, would look more like...
public ILifetimeScope HttpRequestScope
{
get { return AutofacDependencyResolver.Current.RequestLifetime; }
}
There's no analog for a transient scope because usage on that is supposed to be inline:
using(var transientScope = parentScope.BeginLifetimeScope())
{
// Do stuff and resolve dependencies using the transient scope.
// The IDisposable pattern here is important so transient
// dependencies will be properly disposed at the end of the scope.
}
When you register components, you don't register them "into a lifetime scope." You actually register them into a component registry and part of the component registration includes the ownership information about the lifetime of the component once it's resolved.
var builder = new ContainerBuilder();
// This component is factory-scoped and will be "owned" by whatever
// lifetime scope resolves it. You can resolve multiple of these
// in a single scope:
builder.RegisterType<FirstComponent>().As<ISomeInterface>();
// This component is a singleton inside any given lifetime scope,
// but if you have a hierarchy of scopes, you'll get one in each
// level of the hierarchy.
builder.RegisterType<SecondComponent>().InstancePerLifetimeScope();
// This component will be a singleton inside a specifically named
// lifetime scope. If you try to resolve it in a scope without that
// name, it'll search up the scope stack until it finds the scope
// with the right name. If no matching scope is found - exception.
builder.RegisterType<ThirdComponent>().InstancePerMatchingLifetimeScope("scopename");
// This is a per-HTTP-request component. It's just like the
// above InstancePerMatchingLifetimeScope, but it has a special
// tag that the web integration knows about.
builder.RegisterType<FourthComponent>().InstancePerHttpRequest();
If you're trying to make a container/registration agnostic interface, it wouldn't need a "lifetime scope manager" - instead, you'd need to pass some parameters indicating the intended lifetime scope and do the appropriate registration syntax (above) based on the incoming parameters.
Again, I'd recommend you check out that documentation.
Also, if you're using Unity, Autofac does have an Enterprise Library Configurator package that allows you to configure Autofac in a Unity style (since that's how EntLib likes to do things). That might be something to check out.
If you don't need to use Unity syntax at all... I'd recommend just moving to do things the native Autofac way. Trying to make one container look and act like another is a pretty painful endeavor.
Assuming your plugins are in separate assemblies or whatever, you could easily take advantage of some of the nice assembly-scanning syntax along with Autofac modules and hook up your plugins that way.
Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.
I am using windsor castle as my IoC container, and has run in to a bit of a problem. This is best explained in code, so I´ll give it a try.
I have a factory class, that should provide me with implementations of a certain interface:
public interface IObjectCreatorFactory
{
IObjectCreator GetObjectCreator(Type objectType);
}
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
}
Implementation of the factory class could look like this, though I am not sure this is the way to go:
public interface ObjectCreatorFactory:IObjectCreatorFactory
{
IEnumerable specificCreators;
IObjectCreator defaultCreator;
public ObjectCreatorFactory(IEnumerable<IObjectCreator> specificCreators, IObjectCreator defaultCreator)
{
this.specificCreators= specificCreators;
this.defaultCreator= defaultCreator;
}
public IObjectCreator GetObjectCreator(Type objectType)
{
foreach (IObjectCreator creator in specificCreators)
{
if (creator.SupportsType(objectType))
{
return creator;
}
}
return defaultCreator;
}
}
Now this would work out ok, but if I want my IObjectCreator instance to create child objects using a specific IObjectCreator, i would like to call ObjectCreatorFactory, and this obviously results in a circular reference:
public void SpecificObjectCreator:IObjectCreator
{
IObjectCreatorFactory objCreatorFactory;
public SpecificObjectCreator(IObjectCreatorFactory objCreatorFactory)
{
this.objCreatorFactory = objCreatorFactory;
}
T CreateObject<T>(IDataRow data)
{
T obj = new T;
ChildObject childObject = objCreatorFactory.GetObjectCreator(typeof(ChildObject)).CreateObject<ChildObject>(data);
.......
}
bool SupportsType(Type type);
}
This does not work out. What would be the way to go for this scenario, where the created objects are refering back to the factory for child object creators?
I would simply move the factory out of the constructors of the various specific object creators, and introduce a method on the IObjectCreator interface instead, responsible for initialising the creators:
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
void Initialize(IObjectCreatorFactory factory);
}
And then just invoke Initialze(this) on each object creator passed into the factory.
In the past I've used custom life cycle stages to take care of automatically invoking "post-construction" setup of components to both avoid circular dependencies and also to take care of other associated concerns (i.e. applying additional component configuration from an external source like a database) - but it's probably overkill for what you need.