Ferraz
unread,Jun 5, 2012, 8:14:30 PM6/5/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to structuremap-users
Hi,
I need to replace a class injected previously by constructor or
setter. This works fine with a first level, but on a deep dependency
it doesn't work. See the examples:
On " Intercept_With_Dispose_Tudo_OK_Nivel2_test()", if I change the
object to "container.Container" will work fine.
Who can help me?
Tks
public interface IIocIntercept<T> : IDisposable
{
void Intercept(object target, string nameInstanceFrom
, string
nameInstanceTo);
void Undo();
}
public class IocIntercept<T> : IIocIntercept<T>
{
private IList AllInstancesOfT;
private T _InstanceFrom;
private T _InstanceTo;
private object _Target;
public void Intercept(object target, string nameInstanceFrom
, string nameInstanceTo)
{
_InstanceFrom =
ObjectFactory.GetNamedInstance<T>(nameInstanceFrom);
_InstanceTo =
ObjectFactory.GetNamedInstance<T>(nameInstanceTo);
// Faz um Backup
AllInstancesOfT =
ObjectFactory.GetAllInstances(typeof(T));
_Target = target;
// Ejeta tudo do Container
ObjectFactory.EjectAllInstancesOf<T>(); // Não tirar
ObjectFactory.Inject<T>(_InstanceTo);
// faz o build do bagulho
ObjectFactory.BuildUp(target);
}
public void Undo()
{
if (AllInstancesOfT == null) return;
// Ejeta a instância anterior
ObjectFactory.EjectAllInstancesOf<T>();
// Adiciona TODAS do Backup novamente
foreach (T item in AllInstancesOfT)
{
ObjectFactory.Inject(item);
if (item.Equals(_InstanceFrom))
ObjectFactory.BuildUp(_Target);
}
AllInstancesOfT = null;
}
#region IDisposable Members
protected void Dispose(bool disp)
{
if (!disp) return;
this.Undo();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
My tests:
/// <summary>
/// Summary description for InterceptDAL_Tests
/// </summary>
[TestClass]
public class IocIntercept_Tests
{
private IIocIntercept<IClasseInjetada> _InterceptDAL;
public IocIntercept_Tests()
{
_InterceptDAL = new IocIntercept<IClasseInjetada>();
}
private void InicializaComDependenciaNivel1()
{
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.For<IClasseInjetada>().Singleton()
.Use<ClasseInjetadaB>().Named("InstanciaB");
x.For<IClasseInjetada>().Singleton().Use<ClasseInjetadaA>().Named("InstanciaA");
x.For<IClasseContainer>().Singleton().Use<ClasseContainer>();
x.SetAllProperties(o => o.OfType<IClasseInjetada>());
});
}
[TestMethod]
public void Intercept_Just_Replacement_Tudo_OK_test()
{
InicializaComDependenciaNivel1();
// Versão Inicial da Instância
IClasseContainer container =
ObjectFactory.GetInstance<IClasseContainer>();
// Aqui deve estar na forma inicial
Assert.AreEqual(typeof(ClasseInjetadaA),
container.Injetada.GetType());
// Faz a Injeção
_InterceptDAL.Intercept(container, "InstanciaA",
"InstanciaB");
// Confere
Assert.AreEqual(typeof(ClasseInjetadaB),
container.Injetada.GetType());
}
[TestMethod]
public void Intercept_With_Dispose_Tudo_OK_test()
{
InicializaComDependenciaNivel1();
// Versão Inicial da Instância
IClasseContainer container =
ObjectFactory.GetInstance<IClasseContainer>();
// Aqui deve estar na forma inicial
Assert.AreEqual(typeof(ClasseInjetadaA),
container.Injetada.GetType());
using (IIocIntercept<IClasseInjetada> interceptor = new
IocIntercept<IClasseInjetada>())
{
interceptor.Intercept(container, "InstanciaA",
"InstanciaB");
// Confere
Assert.AreEqual(typeof(ClasseInjetadaB),
container.Injetada.GetType());
}
Assert.AreEqual(2,
ObjectFactory.Container.GetAllInstances<IClasseInjetada>().Count);
// Após o Dispose, deve retornar para a versão A
Assert.AreEqual(typeof(ClasseInjetadaA),
container.Injetada.GetType());
}
// Nível 2
private void InicializaComDependenciaNivel2()
{
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.For<IClasseInjetada>().Singleton()
.Use<ClasseInjetadaB>().Named("InstanciaB");
x.For<IClasseInjetada>().Singleton().Use<ClasseInjetadaA>().Named("InstanciaA");
x.For<IClasseContainer>().Singleton().Use<ClasseContainer>();
x.For<IClasseContainerDoContainer>().Singleton().Use<ClasseContainerDoContainer>();
x.SetAllProperties(y =>
y.WithAnyTypeFromNamespace("LeituraDesktop.Tests._Geral"));
});
}
[TestMethod]
public void Intercept_With_Dispose_Tudo_OK_Nivel2_test()
{
InicializaComDependenciaNivel2();
// Versão Inicial da Instância
IClasseContainerDoContainer container =
ObjectFactory.GetInstance<IClasseContainerDoContainer>();
// Aqui deve estar na forma inicial
Assert.AreEqual(typeof(ClasseInjetadaA),
container.Container.Injetada.GetType(), "1º Teste");
using (IIocIntercept<IClasseInjetada> interceptor = new
IocIntercept<IClasseInjetada>())
{
interceptor.Intercept(container, "InstanciaA",
"InstanciaB");
// Confere
Assert.AreEqual(typeof(ClasseInjetadaB)
, container.Container.Injetada.GetType(), "2º
Teste");
}
Assert.AreEqual(2,
ObjectFactory.Container.GetAllInstances<IClasseInjetada>().Count);
// Após o Dispose, deve retornar para a versão A
Assert.AreEqual(typeof(ClasseInjetadaA),
container.Container.Injetada.GetType(), "3º Teste");
}
//
public interface IClasseInjetada
{
string Valor { get; set; }
}
public class ClasseInjetadaA : IClasseInjetada
{
public string Valor { get; set; }
}
public class ClasseInjetadaB : IClasseInjetada
{
public string Valor { get; set; }
}
public interface IClasseContainer
{
IClasseInjetada Injetada { get; set; }
}
public class ClasseContainer : IClasseContainer
{
public IClasseInjetada Injetada { get; set; }
public ClasseContainer(IClasseInjetada ci)
{
Injetada = ci;
}
}
public interface IClasseContainerDoContainer
{
IClasseContainer Container { get; set; }
}
public class ClasseContainerDoContainer :
IClasseContainerDoContainer
{
public IClasseContainer Container{ get; set; }
public ClasseContainerDoContainer(IClasseContainer
container)
{
Container = container;
}
}
}