Windows 서비스에서 Autofac for Ninject를 드롭 인으로 대체하려고 시도 중입니다. (잠재적으로 Autofac 기능을 보완하기 위해 개선하기 전에) 메모리로 실행 중입니다. 발행물. 여기 Autofac이 설치된 Windows 서비스가 참조로 고정
는 우리의 문제를 재현하지 않는 인위적인 예,하지만 응용 프로그램의 현재 레이아웃을 보여줍니다 기본적으로class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
var ms = new MemoryStream(new byte[10000000]);
var ms2 = new MemoryStream(new byte[10000000]);
builder.RegisterType<BaseRepo>()
.WithParameter("ms", ms)
.As<IBaseRepo>();
builder.RegisterType<DerivedRepo>()
.WithParameter("ms", ms2)
.As<IDerivedRepo>();
builder.RegisterType<BaseFactory>().As<IBaseFactory>();
builder.RegisterType<Derived>().AsSelf();
builder.RegisterType<Derived>().Keyed<Base>(BaseEnum.Derived).As<Base>();
var container = builder.Build();
var factory = container.Resolve<IBaseFactory>();
while (true)
{
var instance = factory.Create(BaseEnum.Derived);
instance.DoSomething();
instance.Dispose();
Thread.Sleep(5000);
}
}
}
public interface IDerivedRepo : IDisposable {}
public class DerivedRepo : IDerivedRepo
{
private readonly MemoryStream _ms;
public DerivedRepo(MemoryStream ms)
{
_ms = ms;
}
public void Dispose()
{
_ms.Dispose();
}
}
public interface IBaseRepo : IDisposable {}
public class BaseRepo : IBaseRepo
{
private readonly MemoryStream _ms;
public BaseRepo(MemoryStream ms)
{
_ms = ms;
}
public void Dispose()
{
_ms.Dispose();
}
}
public enum BaseEnum
{
Derived = 1
}
public interface IBaseFactory
{
Base Create(BaseEnum baseEnum);
}
public class BaseFactory : IBaseFactory
{
private readonly IComponentContext _componentContext;
public BaseFactory(IComponentContext componentContext)
{
_componentContext = componentContext;
}
public Base Create(BaseEnum baseEnum)
{
return _componentContext.ResolveOptionalKeyed<Base>(baseEnum);
}
}
public interface IDisposableThing : IDisposable
{
void DoSomething();
}
public abstract class Base : IDisposableThing
{
protected readonly IBaseRepo BaseRepo;
protected Base(IBaseRepo baseRepo)
{
BaseRepo = baseRepo;
}
public void Dispose()
{
Console.WriteLine("Disposing base");
BaseRepo.Dispose();
}
public abstract void DisposeChildren();
public void DoSomething()
{
Console.WriteLine("Doing something");
}
}
public class Derived : Base
{
private readonly IDerivedRepo _derivedRepo;
public Derived(IBaseRepo baseRepo, IDerivedRepo derivedRepo) : base(baseRepo)
{
_derivedRepo = derivedRepo;
}
public override void DisposeChildren()
{
Console.WriteLine("Disposing derived");
_derivedRepo.Dispose();
}
}
를, 우리 - 일정한 간격으로 -의 인스턴스를 인스턴스화하는 공장을 사용 열거 형 값을 기반으로하는 추상 클래스는 해당 인스턴스에서 일부 작업을 수행 한 다음 처리합니다. 문제는 해당 인스턴스가 가비지 수집기에 의해 정리되지 않고 응용 프로그램의 메모리 사용이 꾸준히 증가한다는 것입니다. DebugDiag2는 우리의 repos에있는 MemoryStream
구성원에 해당하는 인스턴스를 보유하고 있다고보고합니다 (실제 응용 프로그램에서는, 이들은 엔티티 프레임 워크 DBContext
에 대한 래퍼입니다. 다른 코드는 분석에서보고되지 않으므로 계속 진행할 것이 없습니다.
확실한 대답을 내놓기에 충분하지 않다는 것을 알고 있습니다. 내가 더 찾고있는 것은 분명히 뭔가 잘못하고있는 부분에 대한 제안입니다. (전체 팀은 Autofac에 익숙하지 않습니다. 서비스 로케이터 방지 패턴,하지만 나는 그것이 우리가보고있는 문제를 일으키지 않는 것으로 가정).